mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
When you use sync IO in the client in a way that needs to be fixed we currently still just provide you with the explanation for server components. The fixes when sync IO happens in the client are not the same as when they happen in a server component so this update adds client specific documentation for these situations. Namely, the key difference is that on the server you can add caching through "use cache" and this is not available to you in the client. sync IO in general is (going to be) allowed in client components broadly as long as Next.js has a fallback UI to prerender. This means that "fixing" sync IO access in the client will usually be solved by wrapping in a Suspense boundary. The alternative is to move the sync IO out of render or move it to the server where it can be cached.
85 lines
3.0 KiB
Plaintext
85 lines
3.0 KiB
Plaintext
---
|
|
title: Cannot infer intended usage of `Math.random()` in a Server Component
|
|
---
|
|
|
|
## Why This Error Occurred
|
|
|
|
A Server Component is calling `Math.random()` without specifying whether it should be cached or whether it should be evaluated on each user Request. If you want this random value to be included in the prerendered HTML for this page you must cache it using `"use cache"`. If you want this random value to be unique per Request you must precede it with `await connection()` so Next.js knows to exclude it from the prerendered HTML.
|
|
|
|
## Possible Ways to Fix It
|
|
|
|
### Cache the random value
|
|
|
|
If your random value is cacheable, move the `Math.random()` call to a `"use cache"` function. For instance, imagine you have a product page and you want to randomize the product order periodically but you are fine with the random order being re-used for different users.
|
|
|
|
Before:
|
|
|
|
```jsx filename="app/page.js"
|
|
export default async function Page() {
|
|
const products = await getCachedProducts()
|
|
const randomSeed = Math.random()
|
|
const randomizedProducts = randomize(products, randomSeed)
|
|
return <ProductsView products={randomizedProducts} />
|
|
}
|
|
```
|
|
|
|
After:
|
|
|
|
```jsx filename="app/page.js"
|
|
export default async function Page() {
|
|
'use cache'
|
|
const products = await getCachedProducts()
|
|
const randomSeed = Math.random()
|
|
const randomizedProducts = randomize(products, randomSeed)
|
|
return <ProductsView products={randomizedProducts} />
|
|
}
|
|
```
|
|
|
|
> **Note**: `"use cache"` is a powerful API with some nuances. If your cache lifetime is too short Next.js may still exclude it from prerendering. Check out the docs for `"use cache"` to learn more.
|
|
|
|
### Indicate the random value is unique per Request
|
|
|
|
If you want the random value to be evaluated on each Request precede it with `await connection()`. Next.js will exclude this Server Component from the prerendered HTML and include the fallback UI from the nearest Suspense boundary wrapping this component instead. When a user makes a Request for this page the Server Component will be rendered and the updated UI will stream in dynamically.
|
|
|
|
Before:
|
|
|
|
```jsx filename="app/page.js"
|
|
export default async function Page() {
|
|
const products = await getCachedProducts()
|
|
const randomSeed = Math.random()
|
|
const randomizedProducts = randomize(products, randomSeed)
|
|
return <ProductsView products={randomizedProducts} />
|
|
}
|
|
```
|
|
|
|
After:
|
|
|
|
```jsx filename="app/page.js"
|
|
import { connection } from 'next/server'
|
|
|
|
async function ProductsSkeleton() {
|
|
...
|
|
}
|
|
|
|
export default async function Page() {
|
|
const products = await getCachedProducts();
|
|
return (
|
|
<Suspense fallback={<ProductsSkeleton />}>
|
|
<DynamicProductsView products={products} />
|
|
</Suspense>
|
|
)
|
|
}
|
|
|
|
async function DynamicProductsView({ products }) {
|
|
await connection();
|
|
const randomSeed = Math.random()
|
|
const randomizedProducts = randomize(products, randomSeed)
|
|
return <ProductsView products={randomizedProducts} />
|
|
}
|
|
```
|
|
|
|
## Useful Links
|
|
|
|
- [`connection` function](/docs/app/api-reference/functions/connection)
|
|
- [`Suspense` React API](https://react.dev/reference/react/Suspense)
|