Next.js에서 데이터 요청은 애플리케이션 사용 방식에 따라 다른 방식으로 콘텐츠를 렌더링한다. 이는 사전 렌더링에 속하는 Static Generation 또는 Server-side Rendering 뿐만 아니라 런타임 시에 콘텐츠를 생성 및 변경하는 Incremental Static Regeneration을 포함한다.
getServerSideProps
페이지에서 getServerSideProps
(Server-side Rendering)을 export하면 Next.js는 매 요청마다 페이지 사전 렌더링 시에 getServerSideProps
가 반환하는 데이터를 활용한다.
getServerSideProps
는 서버 사이드에서만 실행되며, 브라우저 상에서는 실행되지 않는다. 페이지에 getServerSideProps
함수가 정의되어 있다면
getServerSideProps
는 요청 시마다 실행되며, 페이지는 반환된 props를 활용하여 사전 렌더링된다.next/link
또는 next/router
를 통해 클라이언트 사이드에서 페이지 변경을 통해 요청할 때 Next.js는 getServerSideProps
를 실행하는 API 요청을 서버에 보낸다.getServerSideProps
는 페이지에서만 export되며, 페이지 파일이 아닌 파일에서 export될 수 없다. 또한, getServerSideProps
는 단일 함수로 export되야하며 페이지 컴포넌트의 프로퍼티로 getServerSideProps
를 넘겨주면 작동하지 않는다.
자주 변경되는 데이터의 경우에는 클라이언트 사이드에서 데이터 요청을 보내는 것이 좋다. 이런 경우에 데이터는 유저 특정적이며 검색 엔진 최적화에 큰 영향을 주지 않는다.
getStaticPaths
getStaticProps
를 사용하면서 동적 라우트를 사용하는 페이지가 있다면 생성될 경로의 리스트를 정의해줘야한다.
동적 라우트를 사용하는 페이지에서 getStaticPaths
(Static Site Generation) 함수를 호출하면 Next.js는 경로 패턴에 일치하는 모든 경로에 대해 사전 렌더링한다.
getStaticPaths
는 getStaticProps
와 함께 사용되어야하며, getServerSideProps
와 함께 사용될 수 없다.
getStaticPaths
를 사용하는 경우는 다음과 같다.
getStaticProps
는 HTML와 JSON 파일을 생성하는데, 이 둘은 CDN에 캐싱되어 성능을 향상시킨다.getStaticPaths
는 빌드 시점에 서버 사이드에서 실행된다. 만약 Incremental Static Regeneration
을 사용한다면 getStaticPaths
는 백그라운드 요청 시에도 서버 사이드에서 실행된다.
getStaticPaths
는 페이지에서만 export되며, 페이지 파일이 아닌 파일에서 export될 수 없다. 또한, getStaticPaths
는 단일 함수로 export되야하며 페이지 컴포넌트의 프로퍼티로 getStaticPaths
를 넘겨주면 작동하지 않는다.
getStaticProps
페이지에서 getServerSideProps
(Server-side Rendering)을 export하면 Next.js는 매 요청마다 페이지 사전 렌더링 시에 getServerSideProps
가 반환하는 데이터를 활용한다.
getStaticProps
를 사용하는 경우는 다음과 같다.
getStaticProps
는 HTML와 JSON 파일을 생성하는데, 이 둘은 CDN에 캐싱되어 성능을 향상시킨다.Incremental Static Regeneration
와 함께 사용한다면 이전 페이지가 재평가되는 동안 getStaticProps
는 백그라운드에서 실행되고 새로운 페이지가 브라우저에 보여진다. 이는 getStaticProps
가 빌드 시점에서 실행되어 정적 HTML 파일을 생성하기 때문에 들어온 요청에 대한 접근을 제한한다. 만약 페이지의 요청에 접근해야한다면 getStaticProps
에서 사용되는 미들웨어 사용을 고려해야한다.
getStaticProps
를 사용하여 빌드 시점에서 사전 렌더링이 이루어질 때 HTML 파일 뿐만 아니라 getStaticProps
의 반환값을 저장하기 위한 JSON 파일도 생성된다. 이 JSON 파일은 클라이언트 사이드에서 next/link
또는 next/router
에 의한 경로 변경이 일어날 때 페이지 컴포넌트에 props를 넘겨준다.
getStaticProps
는 페이지에서만 export되며, 페이지 파일이 아닌 파일에서 export될 수 없다. 이러한 제약의 이유는 리액트로 페이지를 렌더링할 때 필요한 모든 데이터가 제공되어야하기 때문이다. 또한, getStaticProps
는 단일 함수로 export되야하며 페이지 컴포넌트의 프로퍼티로 getStaticProps
를 넘겨주면 작동하지 않는다.
Incremental Static Regeneration
Next.js는 빌드 후에도 정적 페이지의 생성 및 변경을 허용한다. Icremental Static Regeneration(ISR)은 전체 사이트에 대한 재빌드 과정이 없어도 매 페이지 기반으로 Static Generation을 사용할 수 있게 해준다. ISR을 사용하기 위해서는 getStaticProps
에 props로 revalidate
를 넘겨주면 된다.
export async function getStaticProps() {
const res = await fetch(URL);
const posts = await res.json();
return {
props: {
posts,
},
// Next.js는 요청이 들어올 때 10초 간격으로 페이지를 재생성한다.
revalidate: 10,
};
}
요청이 들어오면 초기에는 빌드 시점에 생성된 캐싱된 페이지를 보여준다.
생성하지 않았던 경로에 대한 페이지에 대한 요청이 들어오면 Next.js는 첫 요청에 대한 응답으로 서버 사이드에서 렌더링한 페이지를 응답하고, 이후의 요청에 대해서는 캐싱된 페이지로 응답한다.
클라이언트 사이드에서 데이터를 요청할 때 유용한 경우는 SEO 인덱싱을 요구하지 않는 페이지, 데이터를 사전 렌더링할 필요가 없는 페이지, 콘텐츠가 자주 변경되는 페이지 등이 있다. 클라이언트 사이드에서는 컴포넌트 수준에서 데이터 요청이 가능하다.
클라이언트 사이드에서 데이터 요청을 할 때는 애플리케이션의 성능과 페이지 로딩 속도에 영향을 준다는 점을 명심해야한다. 이는 데이터 요청이 컴포넌트 및 페이지가 mount될 때 이루어지며, 데이터가 캐싱되지 않기 때문이다.
리액트에서 일반적으로 데이터 요청에 대한 코드를 useEffect
Hook 내에서 처리한다. 이외에 Next.js에서 제공하는 리액트 Hook 라이브러리인 SWR
을 사용할 수도 있다. 이는 매우 권장되는 방법으로 클라이언트 사이드에서 데이터를 요청할 때 캐싱, 재평가, 포커스 트랙킹, 주기적인 재요청 등의 기능들을 사용할 수 있다.
import useSWR from "swr";
const fetcher = (...args) => fetch(...args).then((res) => res.json());
function Profile() {
const { data, error } = useSWR("/api/profile-data", fetcher);
if (error) return <div>Failed to load</div>;
if (!data) return <div>Loading...</div>;
return (
<div>
<h1>{data.name}</h1>
<p>{data.bio}</p>
</div>
);
}