You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Using Experimental `app` Directory in Next.js 13
304
+
305
+
> **WARNING:** The `app` directory introduced in Next.js 13 is currently in beta, and it is not recommended for use in production. The API is not stable.
306
+
>
307
+
> This guide is provided as is to supply a quick start for early exploration of Next.js 13's experimental features and does not represent the final APIs.
308
+
309
+
Both prefetching approaches, using `initialData` or `<Hydrate>`, are available within the `app` directory.
310
+
311
+
- Prefetch the data in a Server Component and prop drill `initialData` to Client Components
312
+
- Quick to set up for simple cases
313
+
- May need to prop drill through multiple layers of Client Components
314
+
- May need to prop drill to multiple Client Components using the same query
315
+
- Query refetching is based on when the page loads instead of when the data was prefetched on the server
316
+
- Prefetch the query on the server, dehydrate the cache and rehydrate it on the client with `<Hydrate>`
317
+
- Requires slightly more setup up front
318
+
- No need to prop drill
319
+
- Query refetching is based on when the query was prefetched on the server
320
+
321
+
### `<QueryClientProvider>` is required by both the `initialData` and `<Hydrate>` prefetching approaches
322
+
323
+
The hooks provided by the `react-query` package need to retrieve a `QueryClient` from their context. Wrap your component tree with `<QueryClientProvider>` and pass it an instance of `QueryClient`.
Fetch your initial data in a Server Component higher up in the component tree, and pass it to your Client Component as a prop.
359
+
360
+
```tsx
361
+
// app/page.jsx
362
+
exportdefaultasyncfunction Home() {
363
+
const initialData =awaitgetPosts()
364
+
365
+
return <Postsposts={initialData} />
366
+
}
367
+
```
368
+
369
+
```tsx
370
+
// app/posts.jsx
371
+
'use client'
372
+
373
+
import { useQuery } from'@tanstack/react-query'
374
+
375
+
exportfunction Posts(props) {
376
+
const { data } =useQuery({
377
+
queryKey: ['posts'],
378
+
queryFn: getPosts,
379
+
initialData: props.posts,
380
+
})
381
+
382
+
// ...
383
+
}
384
+
```
385
+
386
+
### Using `<Hydrate>`
387
+
388
+
Create a request-scoped singleton instance of `QueryClient`. **This ensures that data is not shared between different users and requests, while still only creating the QueryClient once per request.**
Fetch your data in a Server Component higher up in the component tree than the Client Components that use the prefetched queries. Your prefetched queries will be available to all components deeper down the component tree.
400
+
401
+
- Retrieve the `QueryClient` singleton instance
402
+
- Prefetch the data using the client's prefetchQuery method and wait for it to complete
403
+
- Use `dehydrate` to obtain the dehydrated state of the prefetched queries from the query cache
404
+
- Wrap the component tree that needs the prefetched queries inside `<Hydrate>`, and provide it with the dehydrated state
405
+
- You can fetch inside multiple Server Components and use `<Hydrate>` in multiple places
406
+
407
+
> NOTE: TypeScript currently complains of a type error when using async Server Components. As a temporary workaround, use `{/* @ts-expect-error Server Component */}` when calling this component inside another. For more information, see [End-to-End Type Safety](https://beta.nextjs.org/docs/configuring/typescript#end-to-end-type-safety) in the Next.js 13 beta docs.
During server rendering, calls to `useQuery` nested within the `<Hydrate>` Client Component will have access to prefetched data provided in the state property.
428
+
429
+
```tsx
430
+
// app/posts.jsx
431
+
'use client'
432
+
433
+
import { useQuery } from'@tanstack/react-query'
434
+
435
+
exportdefaultfunction Posts() {
436
+
// This useQuery could just as well happen in some deeper child to
437
+
// the "HydratedPosts"-component, data will be available immediately either way
438
+
const { data } =useQuery({ queryKey: ['posts'], queryFn: getPosts })
439
+
440
+
// This query was not prefetched on the server and will not start
441
+
// fetching until on the client, both patterns are fine to mix
442
+
const { data: otherData } =useQuery({
443
+
queryKey: ['posts-2'],
444
+
queryFn: getPosts,
445
+
})
446
+
447
+
// ...
448
+
}
449
+
```
450
+
451
+
As demonstrated, it's fine to prefetch some queries and let others fetch on the client. This means you can control what content server renders or not by adding or removing `prefetchQuery` for a specific query.
452
+
453
+
### Streaming, Suspense and server-side fetching
454
+
455
+
Right now, you always have to `await` the data in the Server Component. In the future, the goal is to be able to _start_ prefetching in a Server Component but not block rendering, instead streaming markup and data to the client incrementally as it gets available. This is currently lacking support in both React and Query.
456
+
457
+
Similarily, you _must_ currently prefetch the data in a Server Component if you want it to be server rendered. A `useQuery()` call even with the `suspense` option enabled will not fetch data on the server, only on the client. We hope to support this in the future, but exact details are still unknown.
458
+
295
459
## Custom SSR with suspense
296
460
297
461
If you do not want to provide `prefetchQuery()` for all your queries in the SSR you can use suspense.
0 commit comments