카테고리 없음

nextjs 13 app router react-query에서 prefetch하여 hydrate하기

Neda 2023. 10. 21. 20:56

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하기

  1. queryClient를 생성 후
  2. 원하는 query를 prefetch
  3. queryClient를 dehydrate하여 <HydrationBoundary>의 props로 전달
  4. 해당 바운더리 안에서 자동으로 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>
  )
}