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
let browserQueryClient:QueryClient|undefined=undefined
48
52
49
53
function getQueryClient() {
50
-
if (typeofwindow==='undefined') {
54
+
if (isServer) {
51
55
// Server: always make a new query client
52
56
returnmakeQueryClient()
53
57
} else {
54
58
// Browser: make a new query client if we don't already have one
55
-
// This is very important so we don't re-make a new client if React
59
+
// This is very important, so we don't re-make a new client if React
56
60
// suspends during the initial render. This may not be needed if we
57
61
// have a suspense boundary BELOW the creation of the query client
58
62
if (!browserQueryClient) browserQueryClient=makeQueryClient()
@@ -354,9 +358,80 @@ The Next.js app router automatically streams any part of the application that is
354
358
355
359
With the prefetching patterns described above, React Query is perfectly compatible with this form of streaming. As the data for each Suspense boundary resolves, Next.js can render and stream the finished content to the browser. This works even if you are using `useQuery` as outlined above because the suspending actually happens when you `await` the prefetch.
356
360
357
-
Note that right now, you have to await all prefetches for this to work. This means all prefetches are considered critical content and will block that Suspense boundary.
361
+
As of React Query v5.40.0, you don't have to `await` all prefetches for this to work, as `pending` Queries can also be dehydrated and sent to the client. This lets you kick off prefetches as early as possible without letting them block an entire Suspense boundary, and streams the _data_ to the client as the query finishes. This can be useful for example if you want to prefetch some content that is only visible after some user interaction, or say if you want to `await` and render the first page of an infinite query, but start prefetching page 2 without blocking rendering.
362
+
363
+
To make this work, we have to instruct the `queryClient` to also `dehydrate` pending Queries. We can do this globally, or by passing that option directly to `hydrate`:
// the function doesn't need to be `async` because we don't `await` anything
402
+
exportdefaultfunction PostsPage() {
403
+
const queryClient =getQueryClient()
358
404
359
-
As an aside, in the future it might be possible to skip the await for "optional" prefetches that are not critical for this Suspense boundary. This would let you kick off prefetches as early as possible without letting them block an entire Suspense boundary, and streaming the _data_ to the client as the query finishes. This could be useful for example if you want to prefetch some content that is only visible after some user interaction, or say if you want to await and render the first page of an infinite query, but start prefetching page 2 without blocking rendering.
405
+
// look ma, no await
406
+
queryClient.prefetchQuery({
407
+
queryKey: ['posts'],
408
+
queryFn: getPosts,
409
+
})
410
+
411
+
return (
412
+
<HydrationBoundarystate={dehydrate(queryClient)}>
413
+
<Posts />
414
+
</HydrationBoundary>
415
+
)
416
+
}
417
+
```
418
+
419
+
On the client, the Promise will be put into the QueryCache for us. That means we can now call `useSuspenseQuery` inside the `Posts` component to "use" that Promise (which was created on the Server):
420
+
421
+
```tsx
422
+
// app/posts/posts.tsx
423
+
'use client'
424
+
425
+
exportdefaultfunction Posts() {
426
+
const { data } =useSuspenseQuery({ queryKey: ['posts'], queryFn: getPosts })
427
+
428
+
// ...
429
+
}
430
+
```
431
+
432
+
> Note that you could also `useQuery` instead of `useSuspenseQuery`, and the Promise would still be picked up correctly. However, NextJs won't suspend in that case and the component will render in the `pending` status, which also opts out of server rendering the content.
433
+
434
+
For more information, check out the [Next.js App with Prefetching Example](../../examples/nextjs-app-prefetching).
360
435
361
436
## Experimental streaming without prefetching in Next.js
362
437
@@ -370,7 +445,11 @@ To achieve this, wrap your app in the `ReactQueryStreamedHydration` component:
you will then have access to `addTodoMutation.variables`, which contain the added todo. In your UI list, where the query is rendered, you can append another item to the list while the mutation is `pending`:
29
+
you will then have access to `addTodoMutation.variables`, which contain the added todo. In your UI list, where the query is rendered, you can append another item to the list while the mutation `isPending`:
Copy file name to clipboardExpand all lines: docs/framework/react/guides/prefetching.md
+6-2Lines changed: 6 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -199,14 +199,18 @@ This starts fetching `'article-comments'` immediately and flattens the waterfall
199
199
If you want to prefetch together with Suspense, you will have to do things a bit differently. You can't use `useSuspenseQueries` to prefetch, since the prefetch would block the component from rendering. You also can not use `useQuery` for the prefetch, because that wouldn't start the prefetch until after suspenseful query had resolved. What you can do is add a small `usePrefetchQuery` function (we might add this to the library itself at a later point):
200
200
201
201
```tsx
202
-
const usePrefetchQuery= (...args) => {
202
+
function usePrefetchQuery(options) {
203
203
const queryClient =useQueryClient()
204
204
205
205
// This happens in render, but is safe to do because ensureQueryData
206
206
// only fetches if there is no data in the cache for this query. This
207
207
// means we know no observers are watching the data so the side effect
208
208
// is not observable, which is safe.
209
-
queryClient.ensureQueryData(...args)
209
+
if (!queryClient.getQueryState(options.queryKey)) {
Copy file name to clipboardExpand all lines: docs/framework/react/react-native.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,6 +5,8 @@ title: React Native
5
5
6
6
React Query is designed to work out of the box with React Native, with the exception of the devtools, which are only supported with React DOM at this time.
7
7
8
+
There is a 3rd party [Expo](https://docs.expo.dev/) plugin which you can try: https://github.com/expo/dev-plugins/tree/main/packages/react-query
9
+
8
10
There is a 3rd party [Flipper](https://fbflipper.com/docs/getting-started/react-native/) plugin which you can try: https://github.com/bgaleotti/react-query-native-devtools
9
11
10
12
There is a 3rd party [Reactotron](https://github.com/infinitered/reactotron/) plugin which you can try: https://github.com/hsndmr/reactotron-react-query
0 commit comments