diff --git a/src/content/reference/react/use.md b/src/content/reference/react/use.md index ab0db0dd8ec..e383408c234 100644 --- a/src/content/reference/react/use.md +++ b/src/content/reference/react/use.md @@ -1537,3 +1537,37 @@ const albums = use(fetchData('/albums')); ``` See [caching Promises for Client Components](#caching-promises-for-client-components) for more details. + +--- + +### `use` returns the value of a different Promise {/*wrong-promise-value*/} + +On the server, React matches each `use` call to its Promise by call order, not by the Promise itself. If a component suspends and runs again, React reuses the Promise already recorded at each position. + +If `use` is called conditionally, and the condition stops `use` from being called once its Promise resolves, the next `use` call takes the skipped position and receives the earlier Promise's value: + +```js +function Album() { + // 🔴 Called on the first attempt, which resolves `tracksPromise` + // and sets `cache.tracks`. Skipped on the attempt after that. + const tracks = cache.tracks ?? use(tracksPromise); + + // Now the 1st `use` call instead of the 2nd, so React returns + // the Promise recorded in that position: `tracksPromise`. + const artist = use(artistPromise); +} +``` + +To fix this, move the `use` calls out of the conditions so the same `use` calls run in the same order on every attempt: + +```js +function Album() { + // ✅ Always the 1st and 2nd `use` calls + const loadedTracks = use(tracksPromise); + const artist = use(artistPromise); + + const tracks = cache.tracks ?? loadedTracks; +} +``` + +This does not affect the browser.