이전 포스트에서 정적 생성(Static Generation)과 서버 사이드 렌더링(Server-Side Renderin)을 알아보았다.
이번 포스트에서는 데이터를 가져오기 위해 Next.js에서 제공하는 세 가지 함수 및 client-side에서 어떻게 데이터를 가져오는지 알아보자.
Next.js에서는 데이터를 가져오기위해 세 가지 함수가 사용된다:
getStaticProps를 async 함수를 통해 내보내기(export)를 하게 되면 Next.js는 getStaticProps 함수에서 반환된 속성 값을 이용하여 사전 렌더링을 하게 된다.
export async function getStaticProps(context) {
return {
props: {}, // will be passed to the page component as props
}
}
`context ` 파라미터는 다음의 키값들을 포함한 객체이다.
`getStaticProps`는 다음 객체를 반환해야 한다.
export async function getStaticProps(context) {
const res = await fetch(`https://...`)
const data = await res.json()
if (!data) {
return {
redirect: {
destination: '/',
permanent: false,
},
}
}
return {
props: { data }, // will be passed to the page component as props
}
}
`getStaticProps`를 사용해야할 때:
Next.js 는 사이트를 빌드 한 후 정적 페이지를 만들거나 업데이트가 가능하다. 증분 정적 재생성(ISR)은 페이지 단위를 기반으로하여 전체 사이트를 다시 빌드하지 않고 정적 생성을 사용할 수 있게 해준다.
증분 정적 재생성은 `revalidate` 속성을 통해 사용이 가능하다.
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}
// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
// Next.js will attempt to re-generate the page:
// - When a request comes in
// - At most once every 10 seconds
revalidate: 10, // In seconds
}
}
// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// the path has not been generated.
export async function getStaticPaths() {
const res = await fetch('https://.../posts')
const posts = await res.json()
// Get the paths we want to pre-render based on posts
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// We'll pre-render only these paths at build time.
// { fallback: blocking } will server-render pages
// on-demand if the path doesn't exist.
return { paths, fallback: 'blocking' }
}
export default Blog
이미 렌더링된 페이지에서 요청이 발생하게 되면, 최초로 캐시가 된 페이지를 보여주게 된다.
`getStaticProps` 의 파일시스템을 통해 파일을 바로 읽어드릴수 있다.
파일을 읽어들이기 위해서는 절대 경로를 알고 있어야한다.
Next.js는 코드를 각기 분리된 디렉토리에서 컴파일하기 때문에 상대경로를 반환하는 `__dirname`을 사용할 수 없다.
대신에 `process.cwd()`를 통해 이를 해결할 수 있다.
import { promises as fs } from 'fs'
import path from 'path'
// posts will be populated at build time by getStaticProps()
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>
<h3>{post.filename}</h3>
<p>{post.content}</p>
</li>
))}
</ul>
)
}
// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries. See the "Technical details" section.
export async function getStaticProps() {
const postsDirectory = path.join(process.cwd(), 'posts')
const filenames = await fs.readdir(postsDirectory)
const posts = filenames.map(async (filename) => {
const filePath = path.join(postsDirectory, filename)
const fileContents = await fs.readFile(filePath, 'utf8')
// Generally you would parse/transform the contents
// For example you can transform markdown to HTML here
return {
filename,
content: fileContents,
}
})
// By returning { props: { posts } }, the Blog component
// will receive `posts` as a prop at build time
return {
props: {
posts: await Promise.all(posts),
},
}
}
export default Blog
`getStaticProps`는 빌드가 진행될 때에만 실행할수 있기 때문에 , query parameters나 정적 HTML을 생성하는 HTTP Headers와 같이 요청 시간에만 유효한 데이터는 받을 수가 없다.
`getStaticProps`는 오직 서버 사이드에서만 실행된다. 클라이언트 사이드에서는 실행되지 않는다. 또한 브라우저를 위한 JS번들에도 포함되지 않는다. 즉, 직접 데이터베이스 쿼리와 같은 코드를 브라우저에 보내지 않고도 작성할 수 있다.
`getStaticProps`에서 API route를 호출하지 않고 함수 내에서 서버 사이드 코드를 직접 작성 해야한다.
`getStaticProps`가 있는 페이지가 빌드간에 미리 렌더링되면 페이지의 HTML 파일 뿐만 아니라 `getStaticProps`의 실행 결과가 포함된 JSON 파일도 같이 생성된다.
이 JSON파일은 `next/link` 또는 `next/router`와 같은 클라이언트 사이드 라우팅에 사용된다. 만약 우리가 `getStaticProps`를 통해 사전에 렌더링된 페이지를 탐색하게 되면, Next.js는 빌드시에 생성된 이 JSON파일을 가져와서 컴포넌트의 속성으로 사용하게된다. 즉, 클라이언트 사이드 페이지의 전환이 `getStaticProps`를 호출하는게 아니라 단순하게 내보내진 JSON 파일만 사용되는 것이다.
`getStaticProps` 함수는 오직 페이지에서만 내보내기가 가능하다. 이러한 제한의 이유는 리액트가 페이지가 렌더되기전에 필요로하는 모든 데이터를 가져야하기 때문이다. 또한 반드시 `export async function getStaticprops{}`를 써야한다. - 단순히 페이지 컴포넌의 속성으로 `getStaticProps`를 사용하게 되면 작동하지 않는다.
`next dev`와 같이 개발 모드에서는 모든 요청에 대해 `getStaticProps`를 호출한다.
몇몇 경우에는 우리는 일시적으로 정적 생성을 피해 빌드시간이 아닌 요청 시간에 페이지를 렌더하고 싶을 때가 있다.
예를 들면 headless CMS 를 사용하고있고 대략적인 퍼블리싱을 미리 보기하고 싶은 경우이다. 이 경우에는 Next.js가 Preview Mode를 지원한다.
지금까지 data fecthing 함수중 getStaticProps에 대해 알아봤다. 다음편에서는 getStaticPaths에 대해 알아보자.
[Next.js] 5. Data Fetching(데이터 가져오기) - getServerSideProps (0) | 2022.07.21 |
---|---|
[Next.js] 4.Data Fetching(데이터 가져오기) - getStaticPaths (0) | 2022.07.20 |
[Next.js] 2. Pages와 렌더링 방식 정리 (0) | 2021.08.27 |
[Next.js] 1. Next.JS 설치 (0) | 2021.08.19 |
댓글 영역