From 5f3ab1bf6830968ca187c87e69c0a732cde9e01c Mon Sep 17 00:00:00 2001 From: Ryan Miller Date: Fri, 12 Jul 2024 09:09:31 +1000 Subject: [PATCH 1/3] chore: update Streaming with Server Components docs to reflect correct usage --- docs/framework/react/guides/advanced-ssr.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/framework/react/guides/advanced-ssr.md b/docs/framework/react/guides/advanced-ssr.md index 10ac86c69c..da02020a15 100644 --- a/docs/framework/react/guides/advanced-ssr.md +++ b/docs/framework/react/guides/advanced-ssr.md @@ -371,7 +371,7 @@ To make this work, we have to instruct the `queryClient` to also `dehydrate` pen // app/get-query-client.ts import { QueryClient, defaultShouldDehydrateQuery } from '@tanstack/react-query' -function makeQueryClient() { +export function getQueryClient() { return new QueryClient({ defaultOptions: { queries: { @@ -439,7 +439,7 @@ If you're using non-JSON data types and serialize the query results on the serve import { QueryClient, defaultShouldDehydrateQuery } from '@tanstack/react-query' import { deserialize, serialize } from './transformer' -export function makeQueryClient() { +export function getQueryClient() { return new QueryClient({ defaultOptions: { // ... @@ -461,11 +461,12 @@ import { HydrationBoundary, QueryClient, } from '@tanstack/react-query' +import { getQueryClient } from './get-query-client' import { serialize } from './transformer' import Posts from './posts' export default function PostsPage() { - const queryClient = new QueryClient() + const queryClient = getQueryClient(); // look ma, no await queryClient.prefetchQuery({ From 041146adfc7a6dc99bd25df9803e820e190f29db Mon Sep 17 00:00:00 2001 From: Ryan Miller Date: Fri, 12 Jul 2024 09:30:01 +1000 Subject: [PATCH 2/3] chore: update Streaming with Server Components to show moving the getQueryClient function --- docs/framework/react/guides/advanced-ssr.md | 30 +++++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/framework/react/guides/advanced-ssr.md b/docs/framework/react/guides/advanced-ssr.md index da02020a15..ce223e4fd2 100644 --- a/docs/framework/react/guides/advanced-ssr.md +++ b/docs/framework/react/guides/advanced-ssr.md @@ -365,21 +365,22 @@ With the prefetching patterns described above, React Query is perfectly compatib 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. -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`: +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`. + +We will also need to move the `getQueryClient()` function out of our `app/providers.jsx` file as we want to use it in our server component and our client provider. ```tsx // app/get-query-client.ts import { QueryClient, defaultShouldDehydrateQuery } from '@tanstack/react-query' -export function getQueryClient() { +function makeQueryClient() { return new QueryClient({ defaultOptions: { queries: { staleTime: 60 * 1000, }, dehydrate: { - // per default, only successful Queries are included, - // this includes pending Queries as well + // include pending queries in dehydration shouldDehydrateQuery: (query) => defaultShouldDehydrateQuery(query) || query.state.status === 'pending', @@ -387,6 +388,22 @@ export function getQueryClient() { }, }) } + +let browserQueryClient: QueryClient | undefined = undefined + +export function getQueryClient() { + if (isServer) { + // Server: always make a new query client + return makeQueryClient() + } else { + // Browser: make a new query client if we don't already have one + // This is very important, so we don't re-make a new client if React + // suspends during the initial render. This may not be needed if we + // have a suspense boundary BELOW the creation of the query client + if (!browserQueryClient) browserQueryClient = makeQueryClient() + return browserQueryClient + } +} ``` > Note: This works in NextJs and Server Components because React can serialize Promises over the wire when you pass them down to Client Components. @@ -439,7 +456,7 @@ If you're using non-JSON data types and serialize the query results on the serve import { QueryClient, defaultShouldDehydrateQuery } from '@tanstack/react-query' import { deserialize, serialize } from './transformer' -export function getQueryClient() { +function makeQueryClient() { return new QueryClient({ defaultOptions: { // ... @@ -452,6 +469,9 @@ export function getQueryClient() { }, }) } + +// ... + ``` ```tsx From e5c9a9c79e7ad58e8bad56281d9ab3c75e5dcb49 Mon Sep 17 00:00:00 2001 From: Ryan Miller Date: Tue, 16 Jul 2024 09:10:13 +1000 Subject: [PATCH 3/3] chore: fix prettier styling --- docs/framework/react/guides/advanced-ssr.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/framework/react/guides/advanced-ssr.md b/docs/framework/react/guides/advanced-ssr.md index ce223e4fd2..bbbac63208 100644 --- a/docs/framework/react/guides/advanced-ssr.md +++ b/docs/framework/react/guides/advanced-ssr.md @@ -471,7 +471,6 @@ function makeQueryClient() { } // ... - ``` ```tsx @@ -486,7 +485,7 @@ import { serialize } from './transformer' import Posts from './posts' export default function PostsPage() { - const queryClient = getQueryClient(); + const queryClient = getQueryClient() // look ma, no await queryClient.prefetchQuery({