개발/Next.js

[Docs] 정적 생성 - getStaticProps 구현 & 세부사항

yoosmg 2023. 5. 10. 07:55

pages/index.js를 열고 Home 컴포넌트 위에다 비동기 함수 getStaticProps를 추가한다.

 

해당 메서드는 getSortedPostsData 함수를 getStaticProps 내부에서 호출한다.

이후 props객체 내부에서 데이터를 반환하여 Home 컴포넌트에 하나의 prop으로 전달할 수 있게 한다.

 

Home 컴포넌트에서 props를 { allPostsData }로 변경하고 <section> 태그를 추가하면 끝.

import { getSortedPostsData } from '../lib/posts';

export async function getStaticProps() {
  const allPostsData = getSortedPostsData();
  return {
    props: {
      allPostsData,
    },
  };
}

export default function Home({ allPostsData }) {
  return (
    <Layout home>
      {/* Keep the existing code here */}

      {/* Add this <section> tag below the existing <section> tag */}
      <section className={`${utilStyles.headingMd} ${utilStyles.padding1px}`}>
        <h2 className={utilStyles.headingLg}>Blog</h2>
        <ul className={utilStyles.list}>
          {allPostsData.map(({ id, date, title }) => (
            <li className={utilStyles.listItem} key={id}>
              {title}
              <br />
              {id}
              <br />
              {date}
            </li>
          ))}
        </ul>
      </section>
    </Layout>
  );
}

이제 http://localhost:3000에 접속하면 블로그 데이터를 볼 수 있을 것이다.

파일 시스템에서 가져온 외부 데이터로 index 페이지를 프리렌더링했음을 의미한다.

 

 

 

이제 추가로 알아야 할 getStaticProps의 몇 가지 세부사항에 대해 알아보자.

 

 

외부 API 페치 / 데이터베이스 쿼리 전부 가능
앞서 우리는 getSortedPostsData는 파일 시스템에서 데이터를 페치 하는 방식으로 사용했었다.

하지만 외부 API 엔드포인트와 같은 다른 소스에서도 페치 하거나 데이터베이스를 직접 쿼리 하는 것도 가능하다.

export async function getSortedPostsData() {
  // Instead of the file system,
  // fetch post data from an external API endpoint
  const res = await fetch('..');
  return res.json();
}
import someDatabaseSDK from 'someDatabaseSDK'

const databaseClient = someDatabaseSDK.createClient(...)

export async function getSortedPostsData() {
  // Instead of the file system,
  // fetch post data from a database
  return databaseClient.query('SELECT posts...')
}

 

이는 getStaticProps가 오직 서버 사이드에서만 실행되기 때문에 가능한 것이다.

클라이언트 사이드에서는 절대 실행되지 않으며 심지어 브라우저의 JS 번들에도 포함되지 않는다.

즉, 데이터베이스 쿼리와 같은 코드를 브라우저로 전송하지 않고 작성해도 된다는 이야기다.

 

 

개발모드에서 vs 프로덕션 모드에서 다른 점

개발 단계에서는 모든 요청에 대해 getStaticProps가 실행된다.

프로덕션 단계에서는 빌드 시점에만 getStaticProps가 실행된다(getStaticPaths가 반환하는 fallback key로개선할 수도 있음).

getStaticProps는 빌드 시점에 실행되도록 되어 있기 때문에, 쿼리 매개변수나 HTTP 헤더와 같이 요청 시에만 사용 가능한 데이터는 사용 불가능 하다.

 

 

페이지 내에서만 허용됨
getStaticProps는 페이지 내 에서만 익스포트 할 수 있다.

페이지가 아닌 파일에서는 익스포트 할 수 없다.
이러한 제한을 두는 이유는 React는 페이지가 렌더링 되기 전에 모든 필수 데이터를 필요로 하기 때문이다.

 

 

요청 시점에 데이터를 페치해야 하는 경우 어떻게 해야 할까
정적 생성은 빌드 시 한 번만 발생하므로 자주 업데이트되거나 사용자 요청 시마다 변경되는 데이터에는 적합하지 않다.

이와 같이 데이터가 변경될 가능성이 있는 경우에는 서버 사이드 렌더링을 사용해 볼 수 있다.

 

Quick Review: Where does getStaticProps run? Server-side