렌더링과 동시에 state에 데이터를 넣고 싶을 때, react에서는 useEffect를 사용하여, componentdidmount를 구현하였다. Next.js에서는 동일한 방법으로 시도를 했더니, 데이터를 받기 전 state의 초기값인 빈 배열이 출력된다. 그 이유는 무엇일까?
pre-rendering
이라는 과정을 통해 HTML을 먼저 브라우저에 띄운 뒤 js파일을 입히는 방식이다.브라우저 요청
-> (라우터) -> 페이지(html file, 데이터 x)
-> react (hydrate : react가 페이지를 SPA로 만들고 제어하려는 작업)
-> hydrate과정에서 useEffect 실행. 함수에 데이터를 불러옴
-> 데이터가 있는, 상호작용이 가능한 페이지 완성
pre-rendering을 통해 반환된 HTML에 데이터가 포함된 페이지를 사전 렌더링 시키려면 위의 NEXT.JS 내장 pre-renderin process를 조정해야 함.
이를 위해 Next.js는 정적 생성(SSG), 서버 사이드 렌더링(SSR). 2가지의 pre-rendering 방식을 제공한다. 본 포스팅에서는 SSG만을 다룬다.
프로덕션을 빌드할 때 사전 렌더링
된다.
- nextjs는 이미 정적인 페이지를 생성하고 빌드 프로세스 중에 페이지를 생성함.
- 페이지 컴포넌트에 데이터를 넣어야 한다면 페이지 컴포넌트 파일 안에서 getStaticProps를 export로 내보내야하며, 이는 페이지 컴포넌트 파일(pages폴더)에서만 작동함.
nextjs는 getStaticProps 함수를 찾아서 사전 렌더링 프로세스 중 이 함수를 실행함.
바로 컴포넌트 함수를 호출하지 않고 반환된 jsx스냅샷을 html 콘텐츠로 사용하지만 컴포넌트 함수를 호출하기 전에 getStaticProps함수를 호출함.
getStaticProps함수는 페이지에서 사용할 props를 준비하는 역할을 함.
getStaticProps는 비동기적으로 설정될 수 있음. next는 async(or promise)가 해결될 때(데이터를 불러올 때)까지 기다린 뒤에 컴포넌트 함수에서 사용할 props를 반환함.
이렇게 하면 컴포넌트가 실행되기 전에 데이터를 읽을 수 있어서 데이터가 포함된 컴포넌트를 렌더링할 수 있음.
getStaticProps 내부의 코드는 빌드 프로세스 중에 실행되기 때문에 클라이언트 측에서 실행되지 않음.
반환하는 객체의 key는 props여야함. 반환하는 props는 해당 페이지 컴포넌트 함수의 매개변수로 받을 수 있음
const Homepage = (props) => {
return <TodoList TodoData={props.todo_list} />;
// 컴포넌트 함수는 props 객체를 받아서 사용할 수 있다.
};
// 비동기로 실행이 가능하며, 데이터를 불러온 뒤에 컴포넌트 함수(Homepage)에서 사용할 prop를 반환한다.
export async function getStaticProps() {
// fetch data from an API
return {
props: {
todo_list: DUMMY_DATA,
},
};
}
export async function getStaticProps() {
// fetch data from an API
return {
props: {
meetups: DUMMY_MEETUPS,
},
// 요청이 들어올 때 페이지를 다시 생성할 때까지 nextjs가 대기하는 시간을 작성
// revalidate속성이 있으면 빌드 프로세스 과정에서 바로 생성되지 않고, 서버에서 몇 초 간격으로 생성됨.
// 10이라면 요청이 들어온 뒤 10초마다 서버에서 페이지를 다시 생성함.
// 숫자는 데이터 업데이트 빈도에 맞게 설정해놓으면 좋음.
revalidate: 3600,
};
export async function getStaticPaths() {
return {
fallback: false,
// fallback 옵션은 사전에 만들어놓을 페이지의 범위를 설정할 수 있다.
// false : paths에 들어간 모든 경로를 제외하고 404 에러를 띄운다.
// true : paths에 들어간 경로는 pre-generate하고, 이외의 요청에 대해 동적으로 생성한다.
paths:
// paths키 객체 배열, 동적 페이지 버전 당 객체가 하나여야 함. (하드 코딩되어 있지만, API를 통해 동적으로 데이터를 넣어줘야 함)
// pre-generate할 페이지 경로를 모음
// 동적 페이지가 여러개 있다면 네스트 객체에 키가 여러 개 있음.
[
{
params: {
meetupId: 'm1',
},
},
{
params: {
meetupId: 'm2',
},
},
],
};
}
export async function getStaticProps(context) {
// fetch data single meetup
const meetupId = context.params.meetupId;
return {
props: {
meetupData: {
image: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/Stadtbild_M%C3%BCnchen.jpg/800px-Stadtbild_M%C3%BCnchen.jpg?20130611211153',
id: meetupId,
title: 'A first Meetup',
address: 'seoul station',
description: 'this is our first meetup ya y',
},
},
};
}