thisyujeong.dev

Pre-rendering 방식으로 데이터 가져오기
June 5, 2021

리액트 훅의 useEffect, useState를 통해 데이터를 관리하면 최초 렌더링시 데이터가 비어있는 경우가 있다.

이 경우 Pre-rendering 방식으로 html에 데이터가 없는 상태로 렌더링되어 검색 엔진 최적화(SEO) 문제가 발생한다.

하지만 이 문제는 Next.js에 내장되어있는 기능을 통해 해결할 수 있으며 두가지 방식이 있다.

  1. 정적 생성 Static Generation
  2. 서버 사이드 렌더링 SSR(Server-Side Rendering)

Static Generation

getStaticProps

정적 생성 방식은 일반적으로 사용하는 접근법으로 getStaticProps 함수를 사용한다.

pages 폴더 내에서만 동작하는 기능으로 최초 렌더링 전 실행되며, Pre-rendering 프로세스의 빌드 과정에서 데이터를 전달받는다.

  • 함수명은 정해진 이름으로 변경할 수 없다.
  • getStaticProps는 반드시 객체를 반환해야한다.
import MeetupList from '../components/meetups/MeetupList';
 
const DUMMY_MEETUPS = [ ... ];
 
function HomePage(props) {
  return <MeetupList meetups={loadedMeetups}></MeetupList>;
}
 
// Static Generation !!
export function getStaticProps() {
	return {
		props: {
			meetups: DUMMY_MEETUPS,
		}
	};
}
 
export default HomePage;

사전 렌더링 시 데이터가 함께 렌더링 된 것을 확인할 수 있다. 이는 NextJS의 강점으로 주요 기능 중 하나이다.

revalidate

점진적 정적 생성

빌드 시 데이터를 가져오기 때문에, 데이터가 변경된다면 문제가 될 수 있다. 변경된 데이터에 따라 주기적인 업데이트가 필요하다. 이를 해결하기 위해 revalidate 를 사용한다.

revalidate 는 숫자를 필요로 한다. 이 숫자는 요청이 들어올 때 이 페이지를 다시 생성할 때까지 대기하는 시간을 초 단위로 표시한 것으로, 어떤 숫자가 설정되어있다면 설정한 초 간격으로 생성된다.

revalidate 값이 10이라면, 이 페이지에 요청이 들어오면 10초마다 서버에서 페이지를 다시 생성한다.

// Static Generation !!
export function getStaticProps() {
  return {
    props: {
      meetups: DUMMY_MEETUPS,
    },
    revalidate: 1, // 1초 마다 페이지를 다시 생성
  };
}

getStaticPaths

getStaticPaths는 데이터에 기초하여 특정 동적 경로를 Pre-rendering 한다.

pages/[id].js 형태의 동적 라우팅 페이지 중, 빌드 시 static하게 생성할 페이지를 명시한다.

  • 미리 명시할 수 없거나 누락된 페이지(404)는 fallback: true 또는 fallbackL'blocking' 으로 제어가능
  • true 는 빈페이지를 렌더링하고 동적으로 생성된 콘텐츠 풀다운
  • blocking 은 페이지가 생성될 때까지 대기하다기 완성된 페이지

SSR (Server-Side Rendering)

getServerSideProps

빌드 과정에서 실행되는 것이 아닌 배포 후 서버에서 모든 요청이 들어올 때마다 실행된다.

auth 와 같은 자격 인증, 세션 접근 등... 필요할 경우 사용한다.

export function getServerSideProps(context) {
  const req = context.req; // request
  const res = context.res; // response
 
  return {
    props: {
      meetups: DUMMY_MEETUPS,
    },
  };
}