From 1fa3d8f586053b41ec94ec3cc002767c4c999a62 Mon Sep 17 00:00:00 2001 From: Lee <43488305+poiu694@users.noreply.github.com> Date: Wed, 15 May 2024 18:14:55 +0900 Subject: [PATCH] refactor: not using useState in creating queryClient when use ReactQueryStreamedHydration in suspense-example --- docs/framework/react/guides/suspense.md | 34 ++++++++++++++++++- .../src/app/providers.tsx | 33 ++++++++++++------ 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/docs/framework/react/guides/suspense.md b/docs/framework/react/guides/suspense.md index 368a331ac1c..78c3de8a461 100644 --- a/docs/framework/react/guides/suspense.md +++ b/docs/framework/react/guides/suspense.md @@ -122,8 +122,40 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import * as React from 'react' import { ReactQueryStreamedHydration } from '@tanstack/react-query-next-experimental' +function makeQueryClient() { + return new QueryClient({ + defaultOptions: { + queries: { + // With SSR, we usually want to set some default staleTime + // above 0 to avoid refetching immediately on the client + staleTime: 60 * 1000, + }, + }, + }) +} + +let browserQueryClient: QueryClient | undefined = undefined + +function getQueryClient() { + if (typeof window === 'undefined') { + // 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 + // supsends 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 + } +} + export function Providers(props: { children: React.ReactNode }) { - const [queryClient] = React.useState(() => new QueryClient()) + // NOTE: Avoid useState when initializing the query client if you don't + // have a suspense boundary between this and the code that may + // suspend because React will throw away the client on the initial + // render if it suspends and there is no boundary + const queryClient = getQueryClient() return ( diff --git a/examples/react/nextjs-suspense-streaming/src/app/providers.tsx b/examples/react/nextjs-suspense-streaming/src/app/providers.tsx index 840ccde40dd..fb0f5a24e97 100644 --- a/examples/react/nextjs-suspense-streaming/src/app/providers.tsx +++ b/examples/react/nextjs-suspense-streaming/src/app/providers.tsx @@ -1,4 +1,3 @@ -// app/providers.jsx 'use client' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' @@ -6,17 +5,29 @@ import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import * as React from 'react' import { ReactQueryStreamedHydration } from '@tanstack/react-query-next-experimental' +function makeQueryClient() { + return new QueryClient({ + defaultOptions: { + queries: { + staleTime: 60 * 1000, + }, + }, + }) +} + +let browserQueryClient: QueryClient | undefined = undefined + +function getQueryClient() { + if (typeof window === 'undefined') { + return makeQueryClient() + } else { + if (!browserQueryClient) browserQueryClient = makeQueryClient() + return browserQueryClient + } +} + export function Providers(props: { children: React.ReactNode }) { - const [queryClient] = React.useState( - () => - new QueryClient({ - defaultOptions: { - queries: { - staleTime: 5 * 1000, - }, - }, - }), - ) + const queryClient = getQueryClient() return (