유명한 담벼락

NextJS에서 React Query 사용하기

by 담담이담
// _app.tsx
import {
  HydrationBoundary,
  QueryClient,
  QueryClientProvider,
} from '@tanstack/react-query'
 
export default function MyApp({ Component, pageProps }) {
  const [queryClient] = useState(
    () =>
      new QueryClient({
        defaultOptions: {
          queries: {
            // 보통 SSR에서는 staleTime을 0 이상으로 해줌으로써
            // 클라이언트 사이드에서 바로 다시 데이터를 refetch 하는 것을 피한다.
            staleTime: 60 * 1000,
          },
        },
      })
  );
 
  return (
    <QueryClientProvider client={queryClient}>
      <HydrationBoundary state={pageProps.dehydratedState}>
        <Component {...pageProps} />
      </HydrationBoundary>
    </QueryClientProvider>
  )
}

 

// pages/posts.jsx
import { dehydrate, HydrationBoundary, QueryClient, useQuery } from '@tanstack/react-query'
 
// This could also be getServerSideProps
export async function getStaticProps() {
  const queryClient = new QueryClient()
 
  await queryClient.prefetchQuery({
    queryKey: ['posts'],
    queryFn: getPosts,
  })
 
  return {
    props: {
      dehydratedState: dehydrate(queryClient),
    },
  }
}
 
function Posts() {
  // 이 쿼리는 Posts의 더 깊은 하위 요소에서도 즉시 데이터를 사용할 수 있다.
  const { data } = useQuery({ queryKey: ['posts'], queryFn: getPosts })
  
  // 이 쿼리는 서버에서 prefetch하지 않는 데이터. 
  // prefetch하는 데이터와 아닌 데이터를 자유롭게 섞어서 활용할 수 있다.
  const { data: commentsData } = useQuery({
    queryKey: ['posts-comments'],
    queryFn: getComments,
  })
 
  // ...
}

 

React Query를 Next.js에서의 서버 사이드 렌더링(SSR)에서 사용할 경우, new QueryClient 키워드를 이용해 QueryClient 인스턴스를 각 페이지마다 생성한다. 이는 각 페이지가 독립적으로 데이터를 관리하고 서로 간섭하지 않기 위함이다. 여러 페이지가 같은`QueryClient` 인스턴스를 공유하면 데이터 캐시가 서로 영향을 주고 받을 수 있다. 각 페이지의 데이터 요청이나 상태를 독립적으로 처리하려고 하는 것이다.

 

별개로 _app.tsx에서 useState를 통해 만들어준 QueryClient 인스턴스는 클라이언트 사이드에서 사용할 QueryClient를 의미한다. 이처럼 Next.js에서는 기존의 리액트 프로젝트와는 다르게 App 컴포넌트 안에 새로운 QueryClient를 useState()를 사용해 state로 선언해 줘야 한다. Next.js에서는 페이지를 이동하면 App 컴포넌트부터 새롭게 렌더링되기 때문에 쿼리 클라이언트가 매번 새롭게 생성되는 것을 막기 위하여 state로 저장해둔다. 이렇게 하면 클라이언트 측에서 페이지 간 데이터를 공유할 수 있기에 앱 전역에서 한 번만 생성된 `QueryClient`를 `useState`를 사용하여 상태로 관리한다. 그래서 CSR 코드에서는 useQueryClient를 사용하여 app.tsx에서 선언한 queryClient를 갖다쓴다.


즉, Next.js에서는 서버 사이드 렌더링(SSR) 시에 각 페이지마다 `QueryClient`를 생성하고 사용하고, 클라이언트 사이드에서는 앱 전역에서 `QueryClient`를 `useState`로 관리하는 것이 일반적인 패턴이다.

 

 

 

블로그의 정보

유명한 담벼락

담담이담

활동하기