nextjs 13 app router react-query에서 prefetch하여 hydrate하기
react query Provider 설정
Provider 컴포넌트를 클라이언트 컴포넌트로 만들어 루트 레이아웃에서 감싸주기
// /app/_components/Provider.tsx
'use client'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import React from 'react'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
type Props = {
children: React.ReactNode
}
const Provider = ({ children }: Props) => {
const [client] = React.useState(
new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: false,
},
},
})
)
return (
<QueryClientProvider client={client}>
{children}
</QueryClientProvider>
)
}
export default Provider
// /app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang='en'>
<body className={`${inter.className}`}>
<Provider>
{children}
</Provider>
</body>
</html>
)
}
react query를 가져오는 유틸 함수 작성
// lib/utils/getQueryCLient.tsx
import { QueryClient } from '@tanstack/react-query'
import { cache } from 'react'
const getQueryClient = cache(() => new QueryClient())
export default getQueryClient
query dehydrate하기
- queryClient를 생성 후
- 원하는 query를 prefetch
- queryClient를 dehydrate하여 <HydrationBoundary>의 props로 전달
- 해당 바운더리 안에서 자동으로 hydrate 되므로 <Series> 컴포넌트에서는 평소처럼 useQuery를 사용하여 사용
// /app/characters/[id]/series/page.tsx
const SeriesPage = async ({ params }: Props) => {
const queryClient = getQueryClient()
await queryClient.prefetchQuery({
queryKey: ['character', params.id, 'series'],
queryFn: () => getSeriesByCharacterId(params.id),
})
const dehydratedState = dehydrate(queryClient)
return (
<HydrationBoundary state={dehydratedState}>
<Series characterId={params.id} />
</HydrationBoundary>
)
}