Next.js Pre-rendering

Hyunwoo Seo·2022년 8월 22일
0

Next.js

목록 보기
4/7
post-thumbnail

getStaticProps

Fetch data at build time, pre-render for Static Generation
공식문서

getStaticProps는 빌드시 고정되는 값으로 빌드 이후에는 수정이 불가능하다.

  • pages/Blog.tsx
// 타입지정을 위해 import
import { GetStaticProps } from 'next'

interface PostInterface {
  userId: number
  id: number
  title: string
  body: string
}

//getStaticProps()에서 받은 데이터값을 props로 받음
function Blog({ posts } : { posts:PostInterface }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}

// getStaticProps 받는 부분
export const getStaticProps: GetStaticProps = async (context) => {
  const res = await fetch('https://.../posts')
  const posts = await res.json()
  
  // 데이터가 없으면 notFound를 보낸다 
  if (!data) {
    return {
      notFound: true,
    }
  }

  //{ props: posts } 빌드타임에 받아서 Blog component로 보낸다
  return {
    props: {
      posts,
    },
  }
}

export default Blog

getStaticProps가 기본 props로 받는 context 객체의 구성은 다음과 같다

params: 다이나믹 라우트 페이지라면, params 는 라우트 파라미터 정보를 가지고 있다.
req: HTTP request object
res: HTTP response object
query: 쿼리스트링
preview: preview 모드 여부
previewData: setPreviewData로 설정된 데이터

getStaticProps가 리턴할 수 있는 값은 다음과 같다

props : 해당 컴포넌트로 리턴할 값 (선택적)
revalidate : 페이지 재생성이 발생할 수 있는 시간(초). 기본값은 false이며, 이게 거짓이면 다음 빌드때까지 페이지가 빌드된 상태로 캐시됨. (선택적)
notFound : Boolean값, 404status를 보내는 것을 허용한다. (선택적)

그렇지만 data를 빌드시에 미리 땡겨와서 static하게 제공하기 때문에 굉장히 빠른 속도로 페이지가 렌더링된다. 따라서 매 유저의 요청마다 fetch할 필요가 없는 데이터를 가진 페이지를 렌더링 할때 매우 유리하다.

  • headless CMS로 부터 데이터가 올때
  • 유저에 구애받지 않고 퍼블릭하게 캐시할 수 있는 데이터
  • SEO 등의 이슈로 인해 빠르게 미리 렌더링 해야만 하는 페이지. getStaticProps는 HTML과 JSON파일을 모두 생성해 두기 때문에, 성능을 향상시키기 위해 CDN 캐시를 하기 쉽다

getStaticPaths (Static Generation)

If a page has dynamic routes and uses getStaticProps it needs to define a list of paths that have to be rendered to HTML at build time.
공식문서

동적라우팅 + getStaticProps를 원할 때 사용한다.
페이지가 동적 라우팅을 쓰고 있고, getStaticProps를 쓰는 경우, getStaticPaths을 통해 빌드 타임 때 정적으로 렌더링할 경로를 설정해야한다.

여기서 정의하지 않은 하위 경로는 접근해도 화면이 뜨지 않는다. 동적라우팅 할 때, 라우팅 되는 경우의 수를 하나하나 집어넣어야 한다.

  • pages/posts/[id].tsx
// 타입지정을 위해 import
import { GetStaticProps } from 'next'

interface PostInterface {
  userId: number
  id: number
  title: string
  body: string
}

// 이 페이지에서 렌더될 컴포넌트 
function Post({ posts } : { posts:PostInterface }) {
   return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}

// 빌드될 때 실행
export const getStaticPaths = async () => {
  // posts를 받기 위해 fetch
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // pre-render할 Path를 얻음 (posts를 통해서)
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))

  // 우리는 오로지 이 path들만 빌드타임에 프리렌더 함 
  // { fallback: false } 는 다른 routes들은 404임을 의미
  // true이면 만들어지지 않은 것도 추후 요청이 들어오면 만들어 줄 거라는 뜻
  return { paths, fallback: false }
}

// 빌드될 때 실행 
export const getStaticProps = async ({ params }) => {
  // params는 post `id`를 포함하고 있다
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  // 해당 페이지에 props로 보냄
  return { props: { post } }
}

export default Post

getStaticPaths가 리턴할 수 있는 값은 다음과 같다

paths : 빌드타임에 pre-rendering할 경로들
fallback : paths 이외의 경로들에 대해 추후 요청이 들어오면 만들어 줄지 말지. 만다면 404를 리턴함.

getServerSideProps

Fetch data on each request. pre-render for Server-side Rendering
공식문서

getServerSideProps는 빌드와 상관없이, 매 페이지 요청마다 데이터를 서버로부터 가져온다.

  • pages/Blog.tsx
// 타입 지정을 위해 import
import { GetServerSideProps } from 'next'

function Page({ data }) {
  console.log(this.props.data)
 //res.json()
}


export const getServerSideProps: GetServerSideProps = async (context) => {
 
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  // data 없을 땐 리턴값을 달리함
   if (!data) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
      },
    }
  }
  
  //pageProps로 넘길 데이터 
  return { props: { data, } }
}

export default Page

getServerSideProps가 기본 props로 받는 context 객체의 구성은 다음과 같다

params: 다이나믹 라우트 페이지라면, params는 라우트 파라미터 정보를 가지고 있다.
req: HTTP request object
res: HTTP response object
query: 쿼리스트링
preview: preview 모드 여부
previewData: setPreviewData로 설정된 데이터

getServerSideProps가 리턴할 수 있는 값은 다음과 같다

props : 해당 컴포넌트로 리턴할 값 (선택적)
redirect : 값 내부와 외부 리소스 리디렉션 허용한다 (선택적) 무조건 { destination: string, permanent: boolean } 의 꼴이어야 한다. 몇몇 드문 케이스에서 오래된 HTTP클라이언트를 적절히 리디렉션하기 위해 커스텀 status코드가 필요할 수 있는데, 그땐 permanent property 대신에 statusCode property를 이용한다.
notFound : Boolean값, 404status를 보내는 것을 허용한다. (선택적)

getServerSideProps는 페이지를 렌더링하기전에 반드시 fetch해야할 데이터가 있을 때 사용한다. 매 페이지 요청시마다 호출되므로 getStaticProps보다 느리지만, 빌드 이후에도 페이지 요청마다 실행된다는 특징이 있다.

  • getServerSideProps는 서버사이드에서만 실행되고, 절대로 브라우저에서 실행되지 않는다.
  • getServerSideProps는 매 요청시 마다 실행되고, 그 결과에 따른 값을 props로 넘겨준 뒤 렌더링을 한다.

출처: https://velog.io/@devstone/Next.js-100-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0-feat.-initialProps-webpack-storybook

0개의 댓글