You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/reference/react/use.md
+32-6Lines changed: 32 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -438,17 +438,43 @@ export async function fetchAlbums() {
438
438
439
439
##### Promises passed to `use` must be cached {/*promises-must-cached*/}
440
440
441
-
Promises created inside a component are recreated on every render because [React doesn't preserve state for renders that suspended before mounting](/reference/react/Suspense#caveats). After each suspension, React retries rendering from scratch, so any Promise created during render is recreated. This causes React to show the Suspense fallback repeatedly and prevents content from appearing. Instead, pass a Promise from a cache, a Suspense-enabled framework, or a Server Component.
441
+
Promises created during render are recreated on every render, which causes React to show the Suspense fallback repeatedly and prevents content from appearing.
442
442
443
-
Common ways a Promise can be unintentionally recreated on every render:
443
+
```js
444
+
functionAlbums() {
445
+
// 🔴 `fetch` creates a new Promise on every render.
446
+
constalbums=use(fetch('/albums'));
447
+
// ...
448
+
}
449
+
```
450
+
451
+
Instead, pass a Promise from a cache, a Suspense-enabled framework, or a Server Component:
452
+
453
+
```js
454
+
// ✅ fetchData reads the Promise from a cache.
455
+
constalbums=use(fetchData('/albums'));
456
+
```
457
+
458
+
</Pitfall>
459
+
460
+
<DeepDive>
461
+
462
+
#### Why are Promises recreated on every render? {/*why-promises-recreated*/}
463
+
464
+
[React doesn't preserve state for renders that suspended before mounting](/reference/react/Suspense#caveats). After each suspension, React retries rendering from scratch, so any Promise created during render is recreated.
465
+
466
+
Common ways a Promise can be unintentionally recreated during render:
444
467
445
468
```js
446
469
functionAlbums() {
447
470
// 🔴 `fetch` creates a new Promise on every render.
448
471
constalbums=use(fetch('/albums'));
449
472
450
-
// 🔴 Calling an async function creates a new Promise on every render.
451
-
constalbums=use(getAlbums());
473
+
// 🔴 Inline `async` function calls create a new Promise on every render.
474
+
constalbums=use((async () => {
475
+
constres=awaitfetch('/albums');
476
+
returnres.json();
477
+
})());
452
478
453
479
// 🔴 Adding `.then` returns a new Promise on every render,
454
480
// even if `fetchData` is cached.
@@ -458,13 +484,13 @@ function Albums() {
458
484
```
459
485
460
486
```js
461
-
// ✅ fetchData reads the promise from a cache.
487
+
// ✅ fetchData reads the Promise from a cache.
462
488
constalbums=use(fetchData('/albums'));
463
489
```
464
490
465
491
Ideally, Promises are created before rendering, such as in an event handler, a route loader, or a Server Component, and passed to the component that calls `use`. Fetching lazily in render delays network requests and can create waterfalls.
0 commit comments