docs: Clarify useSearchParams behavior (#60257)

- `useSearchParams` opts the client component subtree out of static
rendering (pre-rendering), not dynamic rendering. We recommend wrapping
the component that uses `useSearchParams` in a Suspense boundary to
allow client components above it to be statically rendered (part of the
initial HTML).

Closes: https://vercel.slack.com/archives/C03S9JCH2Q5/p1704398859737719
This commit is contained in:
Delba de Oliveira 2024-01-05 13:58:55 +00:00 committed by GitHub
parent 7faf4bd56e
commit 052006b4d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 11 additions and 12 deletions

View file

@ -104,9 +104,6 @@ As a developer, you do not need to choose between static and dynamic rendering a
Dynamic functions rely on information that can only be known at request time such as a user's cookies, current requests headers, or the URL's search params. In Next.js, these dynamic functions are:
- **[`cookies()`](/docs/app/api-reference/functions/cookies) and [`headers()`](/docs/app/api-reference/functions/headers)**: Using these in a Server Component will opt the whole route into dynamic rendering at request time.
- **[`useSearchParams()`](/docs/app/api-reference/functions/use-search-params)**:
- In Client Components, it'll skip static rendering and instead render all Client Components up to the nearest parent Suspense boundary on the client.
- We recommend wrapping the Client Component that uses `useSearchParams()` in a `<Suspense/>` boundary. This will allow any Client Components above it to be statically rendered. [Example](/docs/app/api-reference/functions/use-search-params#static-rendering).
- **[`searchParams`](/docs/app/api-reference/file-conventions/page#searchparams-optional)**: Using the [Pages](/docs/app/api-reference/file-conventions/page) prop will opt the page into dynamic rendering at request time.
Using any of these functions will opt the whole route into dynamic rendering at request time.

View file

@ -414,7 +414,7 @@ The following table provides an overview of how different Next.js APIs affect ca
| [`const revalidate`](#segment-config-options) | | Revalidate or Opt out | Revalidate or Opt out | |
| [`const dynamic`](#segment-config-options) | | Cache or Opt out | Cache or Opt out | |
| [`cookies`](#cookies) | Revalidate (Server Action) | Opt out | | |
| [`headers`, `useSearchParams`, `searchParams`](#dynamic-functions) | | Opt out | | |
| [`headers`, `searchParams`](#dynamic-functions) | | Opt out | | |
| [`generateStaticParams`](#generatestaticparams) | | Cache | | |
| [`React.cache`](#react-cache-function) | | | | Cache |
| [`unstable_cache`](/docs/app/api-reference/functions/unstable_cache) | | | | |
@ -525,7 +525,7 @@ See the [`revalidatePath` API reference](/docs/app/api-reference/functions/reval
### Dynamic Functions
`cookies`, `headers`, `useSearchParams`, and `searchParams` are all dynamic functions that depend on runtime incoming request information. Using them will opt a route out of the Full Route Cache, in other words, the route will be dynamically rendered.
Dynamic functions like `cookies` and `headers`, and the `searchParams` prop in Layouts and Pages depend on runtime incoming request information. Using them will opt a route out of the Full Route Cache, in other words, the route will be dynamically rendered.
#### `cookies`

View file

@ -74,15 +74,15 @@ const searchParams = useSearchParams()
> - `useSearchParams` is a [Client Component](/docs/app/building-your-application/rendering/client-components) hook and is **not supported** in [Server Components](/docs/app/building-your-application/rendering/server-components) to prevent stale values during [partial rendering](/docs/app/building-your-application/routing/linking-and-navigating#4-partial-rendering).
> - If an application includes the `/pages` directory, `useSearchParams` will return `ReadonlyURLSearchParams | null`. The `null` value is for compatibility during migration since search params cannot be known during pre-rendering of a page that doesn't use `getServerSideProps`
## Behavior
### Static Rendering
If a route is [statically rendered](/docs/app/building-your-application/rendering/server-components#static-rendering-default), calling `useSearchParams()` will cause the tree up to the closest [`Suspense` boundary](/docs/app/building-your-application/routing/loading-ui-and-streaming#example) to be client-side rendered.
If a route is [statically rendered](/docs/app/building-your-application/rendering/server-components#static-rendering-default), calling `useSearchParams` will cause the Client Component tree up to the closest [`Suspense` boundary](/docs/app/building-your-application/routing/loading-ui-and-streaming#example) to be client-side rendered.
This allows a part of the page to be statically rendered while the dynamic part that uses `searchParams` is client-side rendered.
This allows a part of the route to be statically rendered while the dynamic part that uses `useSearchParams` is client-side rendered.
You can reduce the portion of the route that is client-side rendered by wrapping the component that uses `useSearchParams` in a `Suspense` boundary. For example:
We recommend wrapping the Client Component that uses `useSearchParams` in a `<Suspense/>` boundary. This will allow any Client Components above it to be statically rendered and sent as part of initial HTML. [Example](/docs/app/api-reference/functions/use-search-params#static-rendering).
For example:
```tsx filename="app/dashboard/search-bar.tsx" switcher
'use client'
@ -170,12 +170,12 @@ export default function Page() {
}
```
## Behavior
### Dynamic Rendering
If a route is [dynamically rendered](/docs/app/building-your-application/rendering/server-components#dynamic-rendering), `useSearchParams` will be available on the server during the initial server render of the Client Component.
> **Good to know**: Setting the [`dynamic` route segment config option](/docs/app/api-reference/file-conventions/route-segment-config#dynamic) to `force-dynamic` can be used to force dynamic rendering.
For example:
```tsx filename="app/dashboard/search-bar.tsx" switcher
@ -248,6 +248,8 @@ export default function Page() {
}
```
> **Good to know**: Setting the [`dynamic` route segment config option](/docs/app/api-reference/file-conventions/route-segment-config#dynamic) to `force-dynamic` can be used to force dynamic rendering.
### Server Components
#### Pages