main-logo

Next.js Data Fetching

넥스트JS로 데이터 패칭하기

profile
TY
2023년 02월 05일 · 0 분 소요

들어가며

Next.js로 Data를 Fetching 하는 방법에 대해 알아보자.

이번에 Next.js를 이용한 환경에서 데이터를 가져와야 하는 작업을 하게 되었다.
그로 인해 검색을 통해 이런저런 블로그 글과 공식 문서를 보며 알아가는 와중에 이 내용에 대해 우리 블로그에 작성하면 되겠다 생각이 들어 작성하였다.

우선 Next.js의 사전 렌더링에 대해 알아야 하므로 간략하게 이 부분부터 정리하고 나서 본격적인 Data Fetching에 대해 알아보자.

Pre-rendering(사전 렌더링)


사전 렌더링은 크게 2가지로 나뉜다.

Static Generation(정적 생성)과 Server-side Rendering(서버 측 렌더링)으로 나뉘는데, 공식문서상에는 Static Generation(정적 생성)의 사용을 추천하고 있다. 그런데 추천은 추천일뿐 상황에 따라 적합한 방법을 사용하는 게 좋을 거 같다.

Static Generation(정적 생성)

HTML은 빌드 시 생성되며 각 요청에서 재사용된다.
사용자의 요청에 앞서 미리 렌더링할 수 있는 페이지에 적합하다. getStaticProps 나 getStaticPaths를 이용하여 외부 데이터를 의존하여 HTML을 생성할 수 있다. 또한 클라이언트 측 렌더링과 함께 사용하여 추가 데이터를 가져올 수도 있다.

Server-side Rendering(서버 측 렌더링)

HTML은 각 요청에서 생성된다.
페이지에서 서버 측 렌더링을 사용하도록 하려면 getServerSideProps를 사용하면 되며, 서버 측 렌더링은 정적 생성보다 성능이 느리기 때문에 필요한 경우에만 사용하도록 하자.

Data Fetching


그러면 이제 Next.js에서 데이터를 가져오는 방법에 대해 알아보자.

빌드시 데이터를 가져오기(getStaticProps)

외부 데이터를 받아 HTML을 Static Generation(정적 생성) 하기 위한 용도다.

export async function getStaticProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  };
}

getStaticProps를 언제 사용해야 하는지에 대해서는 공식문서에 여러 가지가 나와 있는데, 간단하게 정리하자면 다음과 같다고 생각하면 될 듯하다.

화면에서 사용하는 데이터가 외부 데이터인데, 실시간으로 바뀌는 데이터가 아닌 경우에 사용한다고 생각하자.

빌드시 데이터를 가져오고, 일정 시간마다 업데이트하기(Incremental Static Regeneration)

줄여서 ISR이라고 한다. 빌드시 생성된 HTML을 일정 시간마다 데이터를 다시 업데이트하여 HTML을 재생성한다.

사용법은 getStaticProps에 revalidate 값을 추가해주면 된다.

export async function getStaticProps() {
  const res = await fetch('https://.../posts');
  const posts = await res.json();

  return {
    props: {
      posts,
    },
    revalidate: 10, // In seconds, ex) 60 * 60 = 1 hour
  };
}

데이터가 자주 바뀌지는 않지만, 주기적으로 업데이트를 해야 할 때 사용하면 되겠다.
참고로 revalidate에 설정한 시간이 지나면 자동으로 HTML을 재생성 하는 것이 아닌 설정한 시간 이후 해당 페이지의 요청이 있을 때 HTML이 재생성 된다.

HTML을 요청할 때마다 데이터를 가져오기(getServerSideProps)

페이지 진입 때마다 데이터를 호출하여 SSR로 HTML을 생성한다.

사용법은 getStaticProps와 큰 차이점은 없다.

export async function getServerSideProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  };
}

getServerSideProps를 언제 사용해야 하는지에 대한 건 명확하다.
화면 요청 시 데이터를 가져와야 하는 페이지를 렌더링해야 하는 경우에만 사용해야 한다.

Client-side data fetching

위에서 소개한 방법 외에 페이지 진입 시 데이터를 요청한 후 실시간으로 데이터가 업데이트 돼야 하는 경우에는 클라이언트에서 데이터를 호출하여야 한다.

이는 평소 React에서 useEfeect를 이용하여 데이터를 호출하는 방법과 큰 차이가 없다.

import { useState, useEffect } from 'react';

function Profile() {
  const [data, setData] = useState(null);
  const [isLoading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);
    fetch('/api/profile-data')
      .then((res) => res.json())
      .then((data) => {
        setData(data);
        setLoading(false);
      });
  }, []);

  if (isLoading) return <p>Loading...</p>;
  if (!data) return <p>No profile data</p>;

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.bio}</p>
    </div>
  );
}

마치며

Next.js에서 데이터를 가져오는 방법에 대해 알아보았다.

그동안 일반적인 클라이언트 환경에서의 데이터를 호출하는 작업은 몇 번 해봤으나, Next.js 처럼 서버 사이드에서 렌더링을 하는 방식에서는 처음 해보는 방식이라서 이런저런 자료와 여러 문서를 보며 습득하고 파악한 내용을 정리해 보았다. (돌고 돌아 결국엔 공식 문서로…)

나처럼 처음 접하는 사람들에게 도움이 되었으면 하는 마음에서 작성하였는데, 누군가에게 조금이나마 도움이 되었으면 한다.

참고 문서