Skip to content

Commit a5ee742

Browse files
committed
Split Pitfall and DeepDive, clarify recreation examples
1 parent d6aa254 commit a5ee742

1 file changed

Lines changed: 32 additions & 6 deletions

File tree

  • src/content/reference/react

src/content/reference/react/use.md

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,17 +438,43 @@ export async function fetchAlbums() {
438438
439439
##### Promises passed to `use` must be cached {/*promises-must-cached*/}
440440
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.
442442
443-
Common ways a Promise can be unintentionally recreated on every render:
443+
```js
444+
function Albums() {
445+
// 🔴 `fetch` creates a new Promise on every render.
446+
const albums = 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+
const albums = 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:
444467
445468
```js
446469
function Albums() {
447470
// 🔴 `fetch` creates a new Promise on every render.
448471
const albums = use(fetch('/albums'));
449472

450-
// 🔴 Calling an async function creates a new Promise on every render.
451-
const albums = use(getAlbums());
473+
// 🔴 Inline `async` function calls create a new Promise on every render.
474+
const albums = use((async () => {
475+
const res = await fetch('/albums');
476+
return res.json();
477+
})());
452478

453479
// 🔴 Adding `.then` returns a new Promise on every render,
454480
// even if `fetchData` is cached.
@@ -458,13 +484,13 @@ function Albums() {
458484
```
459485
460486
```js
461-
// ✅ fetchData reads the promise from a cache.
487+
// ✅ fetchData reads the Promise from a cache.
462488
const albums = use(fetchData('/albums'));
463489
```
464490
465491
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.
466492
467-
</Pitfall>
493+
</DeepDive>
468494
469495
---
470496

0 commit comments

Comments
 (0)