React Query를 사용하는 첫 번째 단계는 queryClient를 생성하고 어플리케이션을 로 감싸는 것이다.
서버 렌더링을 할 때는 앱 내에서 리액트 상태에 queryClient 인스턴스를 생성하는 것이 중요하다. 이렇게 하면 데이터가 서로 다른 유저와 요청들 사이에 공유되지 않고, 컴포넌트 라이프사이클당 한 번만 queryClient가 생성된다.
// app/root.tsx
import { Outlet } from "@remix-run/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
export default function MyApp() {
const [queryClient] = React.useState(
() =>
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,
},
},
})
);
return (
<QueryClientProvider client={queryClient}>
<Outlet />
</QueryClientProvider>
);
}
코드 설명
const [queryClient] = React.useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000,
},
},
})
);
QueryClient란?
React Query에서 데이터를 캐싱하고 상태를 관리하는 객체
useState를 사용하는 이유
defaultOptions
QueryClient를 초기화할 때의 기본 설정
return (
<QueryClientProvider client={queryClient}>
<Outlet />
</QueryClientProvider>
);
QueryClientProvider란?
useQuery, useMutation 등)을 사용할 수 있음QueryProvider 코드// In Next.js, this file would be called: app/providers.tsx
'use client'
// Since QueryClientProvider relies on useContext under the hood, we have to put 'use client' on top
import {
isServer,
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query'
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 (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
}
}
export default function Providers({ children }: { children: React.ReactNode }) {
// 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 (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
)
}
코드 설명
let browserQueryClient: QueryClient | undefined = undefined
function getQueryClient() {
if (isServer) {
return makeQueryClient()
} else {
if (!browserQueryClient) browserQueryClient = makeQueryClient()
return browserQueryClient
}
}
브라우저 환경에서 QueryClient를 한 번만 생성하여 재사용하기 위해 싱글톤 변수로 선언
서버 환경
브라우저 환경
Suspense 문제 방지
[참고문서]
https://tanstack.com/query/v5/docs/framework/react/guides/ssr
https://tanstack.com/query/v5/docs/framework/react/guides/advanced-ssr