Next.js와 React Query로 서버 사이드 데이터 패칭 최적화하기

0

서버 사이드 렌더링(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 애플리케이션에서 더욱 효율적이고 성능 좋은 서버 사이드 데이터 패칭을 구현해보세요!

Leave a Reply