본 게시물은 Next 에서의 Data Fetching에 대해서 다루고 있다.
getStaticProps를 사용하게 되면, Next.js는 getStaticProps를 사용하여 리턴된 props를 이용하여 페이지를 빌드 타임에 pre-render한다.
export async function getStaticProps(context) {
return {
props: {}, // will be passed to the page component as props
}
}
// lib/load-posts.js
// The following function is shared
// with getStaticProps and API routes
// from a `lib/` directory
export async function loadPosts() {
// Call an external API endpoint to get posts
const res = await fetch('https://.../posts/')
const data = await res.json()
return data
}
// pages/blog.js
import { loadPosts } from '../lib/load-posts'
// This function runs only on the server side
export async function getStaticProps() {
// Instead of fetching your `/api` route you can call the same
// function directly in `getStaticProps`
const posts = await loadPosts()
// Props returned will be passed to the page component
return { props: { posts } }
}
실제 사용 예시
import type { NextPage } from 'next';
interface Props {
data: number;
}
const Example: NextPage<Props> = ({ data }) => {
return (
<main>
<h1>getStaticProps Page</h1>
<p>값: {data}</p>
</main>
);
};
export default Example;
export async function getStaticProps() {
const delayInSeconds = 2;
const data = await new Promise((resolve) =>
setTimeout(() => resolve(Math.random()), delayInSeconds * 1000)
);
return {
props: { data },
};
}
2초마다 데이터를 받아서 그 결과를 화면에 뿌려주는 결과이다. 기대에는 pre-rendering이 실행되기 때문에 html값이 이미 고정되어 나타나야 하는 것처럼 보이나, dev환경에서는 새로고침 될 때마다 getStaticProps 함수가 다시 실행된다.
getStaticProps는 page에서만 사용될 수 있다. _app, _document, _error에서 사용할 수 없다.
이렇게 getStaticProps를 이용하여 빌드 타임에 API를 한번만 불러오고 끝나게 되면 안된다. 빌드가 이루어지고 나서도 API가 수정되어 데이터의 값이 바뀌게 될 수도 있다. 그럴 때를 대비하여 만들어진 것이 바로 revaildate를 이용하는 것이다.
export async function getStaticProps() {
const delayInSeconds =2;
const data = await new Promise((reslove)=> setTimeout(()=> resolove(Math.random()),delayInSeconds * 1000));
return {
props: {data},
revalidate: 5,
}
}
import Link from 'next/link';
export default function Links() {
return (
<main>
<h1>Links</h1>
<Link href="/section1/getStaticProps">/getStaticProps</Link>
</main>
);
}
이런식으로 진행하게 되면 getStaticProps 페이지로 이동을 하였지만 html 파일은 새로 로드되지 않았고, getStaticProps 페이지와 관련된 js파일과 json 파일만 새로 로드된 것을 알 수 있다. CSR의 랜더링 방식과 매우 유사하여 라우팅과 관련하여 매우 부드럽고 빠르게 수행되고 있는 것을 알 수 있다.
만약 a 태그로 해당 부분을 바꾸어 실행한다면 json과 js파일은 미리 로드되어 있지 않으며, html파일이 새로 로딩된다.
getServerSideProps는 getStaticProps와 비슷하지만, 서버 사이드 렌더링을 위한 함수이다. 요청이 들어올 때마다 호출되고, 그 때마다 사전 렌더링을 진행한다.
getStaticProps와는 다르게 요청이 들어올 때마다 호출되기에 빌드 이후 자주 바뀌는 동적 데이터가 들어갈 때 사용하기 좋다
import type { GetServerSideProps, NextPage } from 'next';
interface Props {
data: number;
}
const Example: NextPage<Props> = ({ data }) => {
return (
<main>
<h1>getServerSideProps Page</h1>
<p>값: {data}</p>
</main>
);
};
export default Example;
export const getServerSideProps: GetServerSideProps = async ({ res }) => {
const delayInSeconds = 2;
const data = await new Promise((resolve) =>
setTimeout(() => resolve(Math.random()), delayInSeconds * 1000)
);
return {
props: { data },
};
};