서버 사이드 렌더링(SSR)과 클라이언트 사이드 렌더링(CSR)을 일관되게 수행하려면, Next.js와 React Query의 조합이 강력한 도구가 됩니다. 이 글에서는 `getServerSideProps`, `dehydrate()`, `QueryClient`, 그리고 `HydrationBoundary`를 활용하여 데이터를 효율적으로 패칭하고 관리하는 방법을 단계별로 알아보겠습니다.
1. 서버 사이드 데이터 패칭을 위한 getServerSideProps
Next.js에서 서버 사이드 렌더링을 지원하는 `getServerSideProps` 함수는 페이지 요청 시마다 서버에서 실행됩니다. 이를 통해 최신 데이터를 패칭하고 페이지에 전달할 수 있습니다.
import { GetServerSideProps } from 'next'; export const getServerSideProps: GetServerSideProps = async (context) => { const { params, req, query } = context; // 예시: params에서 동적 경로 값 가져오기 const id = params?.id; // 예시: req에서 요청 헤더 접근하기 const userAgent = req.headers['user-agent']; // 예시: query에서 쿼리 문자열 값 가져오기 const searchQuery = query.search; // 데이터를 패칭하고, 페이지 컴포넌트로 전달합니다. const data = await fetchData(id, searchQuery); return { props: { data, userAgent, }, }; }; const MyPage = ({ data, userAgent }) => { return ( <div> <h1>Data: {data}</h1> <p>User Agent: {userAgent}</p> </div> ); }; export default MyPage;
2. React Query의 QueryClient 이해하기
React Query는 데이터 패칭과 캐싱을 간편하게 해주는 라이브러리입니다. `QueryClient`는 React Query의 핵심 인스턴스로, 데이터 상태 관리, 캐싱, 동기화 등을 담당합니다.
import { QueryClient, QueryClientProvider } from 'react-query'; import { ReactQueryDevtools } from 'react-query/devtools'; const queryClient = new QueryClient(); function MyApp({ Component, pageProps }) { return ( <QueryClientProvider client={queryClient}> <Component {...pageProps} /> <ReactQueryDevtools initialIsOpen={false} /> </QueryClientProvider> ); } export default MyApp;
3. 서버 사이드 데이터 직렬화를 위한 dehydrate()
서버 사이드에서 데이터를 패칭하고 직렬화하여 클라이언트에 전달하려면 `dehydrate()` 함수를 사용합니다. 이를 통해 React Query의 캐시된 데이터를 클라이언트에 전송할 수 있습니다.
import { QueryClient, dehydrate } from 'react-query'; export async function getServerSideProps() { const queryClient = new QueryClient(); await queryClient.prefetchQuery('todos', fetchTodos); return { props: { dehydratedState: dehydrate(queryClient), }, }; } function TodosPage({ dehydratedState }) { return ( <HydrationBoundary state={dehydratedState}> <Todos /> </HydrationBoundary> ); } export default TodosPage;
4. 클라이언트 사이드 데이터 복원: HydrationBoundary
서버 사이드에서 직렬화된 데이터를 클라이언트 사이드에서 복원하기 위해 `HydrationBoundary` 컴포넌트를 사용합니다. 이를 통해 서버와 클라이언트 간 데이터 일관성을 유지합니다.
import { HydrationBoundary } from 'react-query'; function TodosPage({ dehydratedState }) { return ( <HydrationBoundary state={dehydratedState}> <Todos /> </HydrationBoundary> ); } export default TodosPage;
요약 및 결론
이 글에서는 Next.js와 React Query를 사용하여 서버 사이드와 클라이언트 사이드에서 데이터를 일관되게 패칭하고 관리하는 방법을 다루었습니다. `getServerSideProps`, `QueryClient`, `dehydrate()`, `HydrationBoundary` 등을 활용하여 서버에서 데이터를 미리 패칭하고, 클라이언트에서 이를 복원함으로써 빠르고 일관된 사용자 경험을 제공할 수 있습니다. 이 과정은 데이터 일관성을 유지하고 초기 로딩 시간을 최적화하는 데 큰 도움이 됩니다.
이러한 방법을 통해 여러분의 Next.js 애플리케이션에서 더욱 효율적이고 성능 좋은 서버 사이드 데이터 패칭을 구현해보세요!