Skip to content

Commit d618240

Browse files
committed
docs(Suspense): warn against module-level cache in SSR
Add a Pitfall on the Suspense reference page explaining that the hidden data.js cache must not be copied into server environments like Next.js, where module-level state can leak data across requests. Clarify the data.js comment in all Suspense examples accordingly. Fixes #8134
1 parent 12d692d commit d618240

1 file changed

Lines changed: 22 additions & 0 deletions

File tree

src/content/reference/react/Suspense.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ React will display your <CodeStep step={1}>loading fallback</CodeStep> until all
7979

8080
In the example below, the `Albums` component *suspends* while fetching the list of albums. Until it's ready to render, React switches the closest Suspense boundary above to show the fallback--your `Loading` component. Then, when the data loads, React hides the `Loading` fallback and renders the `Albums` component with data.
8181

82+
<Pitfall>
83+
84+
Do not use a module-level cache like the one in `data.js` below in server environments such as Next.js. Module-level state persists across requests and can leak data between users. Use your framework's built-in caching, [`cache`](/reference/react/cache) in Server Components, or scope caches per request (for example, with a Context and `useRef`).
85+
86+
</Pitfall>
87+
8288
<Sandpack>
8389

8490
```js src/App.js hidden
@@ -148,6 +154,8 @@ export default function Albums({ artistId }) {
148154
// Note: the way you would do data fetching depends on
149155
// the framework that you use together with Suspense.
150156
// Normally, the caching logic would be inside a framework.
157+
// This module-level cache is only suitable for this client-only demo.
158+
// Do not copy it into server environments.
151159

152160
let cache = new Map();
153161

@@ -606,6 +614,8 @@ export default function Albums({ artistId }) {
606614
// Note: the way you would do data fetching depends on
607615
// the framework that you use together with Suspense.
608616
// Normally, the caching logic would be inside a framework.
617+
// This module-level cache is only suitable for this client-only demo.
618+
// Do not copy it into server environments.
609619

610620
let cache = new Map();
611621

@@ -868,6 +878,8 @@ export default function Albums({ artistId }) {
868878
// Note: the way you would do data fetching depends on
869879
// the framework that you use together with Suspense.
870880
// Normally, the caching logic would be inside a framework.
881+
// This module-level cache is only suitable for this client-only demo.
882+
// Do not copy it into server environments.
871883

872884
let cache = new Map();
873885

@@ -1052,6 +1064,8 @@ export default function SearchResults({ query }) {
10521064
// Note: the way you would do data fetching depends on
10531065
// the framework that you use together with Suspense.
10541066
// Normally, the caching logic would be inside a framework.
1067+
// This module-level cache is only suitable for this client-only demo.
1068+
// Do not copy it into server environments.
10551069

10561070
let cache = new Map();
10571071

@@ -1236,6 +1250,8 @@ export default function SearchResults({ query }) {
12361250
// Note: the way you would do data fetching depends on
12371251
// the framework that you use together with Suspense.
12381252
// Normally, the caching logic would be inside a framework.
1253+
// This module-level cache is only suitable for this client-only demo.
1254+
// Do not copy it into server environments.
12391255

12401256
let cache = new Map();
12411257

@@ -1495,6 +1511,8 @@ export default function Panel({ children }) {
14951511
// Note: the way you would do data fetching depends on
14961512
// the framework that you use together with Suspense.
14971513
// Normally, the caching logic would be inside a framework.
1514+
// This module-level cache is only suitable for this client-only demo.
1515+
// Do not copy it into server environments.
14981516

14991517
let cache = new Map();
15001518

@@ -1807,6 +1825,8 @@ export default function Panel({ children }) {
18071825
// Note: the way you would do data fetching depends on
18081826
// the framework that you use together with Suspense.
18091827
// Normally, the caching logic would be inside a framework.
1828+
// This module-level cache is only suitable for this client-only demo.
1829+
// Do not copy it into server environments.
18101830

18111831
let cache = new Map();
18121832

@@ -2118,6 +2138,8 @@ export default function Panel({ children }) {
21182138
// Note: the way you would do data fetching depends on
21192139
// the framework that you use together with Suspense.
21202140
// Normally, the caching logic would be inside a framework.
2141+
// This module-level cache is only suitable for this client-only demo.
2142+
// Do not copy it into server environments.
21212143

21222144
let cache = new Map();
21232145

0 commit comments

Comments
 (0)