[Next.js] pre-rendering 관련

jiseong·2022년 3월 23일
0

T I Learned

목록 보기
202/291

드디어 Next.js를 학습하고자 했던 가장 중요한 이유 중 하나인 Pre-rendering 개념이 등장했다.

기본적으로 Next.js는 모든 페이지를 Pre-render하는데 이는 React에서 학습했던 CSR와 비교하자면 각 페이지에 대해서 미리 HTML을 만들어 사용자에게 전달하는 것을 의미한다.

React로 만들었던 서비스 Pre-rendering 테스트

크롬의 개발자도구를 켜고 Command+Shift+P (Mac) 누른 뒤 javascript을 입력 후 javascript를 disable 시킨 다음 사이트에 접속하면 다음과 같이 보이게 되는데 React는 클라이언트 측에서 js를 사용해서 화면을 보여주기 때문이다.

Pre-rendering vs No Pre-rendering

SSG & SSR

Next.js 에서는 2가지 형태의 Pre-Rendering을 사용한다.

SSG

  • Static Site Generation : HTML을 빌드 타임에 생성하고 각 요청에 따라서 재사용 (SSG)

SSG를 사용하더라도 data와 함께 사용이 가능하지만 최신 데이터임을 보장해줄 수는 없다. (옵션을 추가적으로 설정하여 해결할수도 있긴 하다)

const Home = ({posts}: PostsProps) => {
  return (
    <div>
      <main>
        <section>
          <h2>Blog</h2>
          <ul>
            {posts && posts.map(({ id, userId, title, body }) => (
              <Post key={id} userId={userId} title={title} body={body} />
            ))}
          </ul>
        </section>
      </main>
    </div>
  )
}

export default Home;


export async function getStaticProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts');
  const allPostsData = await res.json();

  return {
    props: {
      posts: allPostsData
    }
  }
}

개발모드 (npm run dev)에서는 SSG를 사용한 페이지여도 리퀘스트가 일어날 때 마다 생성한다고 한다.

해당 코드를 빌드해보면 다음과 같이 미리 HTML을 만들어 놓은 것을 볼 수 있다.

SSR

  • Server Side Rendering : HTML을 각 리퀘스트가 일어날 때 마다 생성 (SSR)

리퀘스트 시점마다 데이터를 fetch하기 위해서는 getServerSideProps을 사용하면 된다.

위에서 사용했던 jsonPlaceholder api를 사용하여 테스트를 해보았다.

interface Props {
  postData: PostProps;
}

function PostDetail({ postData }: Props) {
  const { userId, title, body } = postData;

  return (
    <ul>
      <Post userId={userId} title={title} body={body} />
    </ul>
  );
}

export default PostDetail;

export const getServerSideProps: GetServerSideProps = async (context) => {
  const { id } = context.query;
  const res = await fetch(`${JSONPLACEHOLDER_URL}/posts/${id}`);
  const postData = await res.json();

  if (res.status === STATUS_CODES.NOT_FOUND) {
    return {
      redirect: {
        permanent: false,
        destination: '/',
      },
    };
  }

  return {
    props: {
      postData,
    },
  };
};

여기서 context에서 반환되는 값이 어떤 것인지 궁금했는데 여러 키를 가지고 있는 객체라고 한다.

하나를 예시로 들면 이전의 포스트에서 다이나믹 라우팅을 위해 /pages/post/[id].tsx를 생성했다면 params key 값에 라우터 파라미터가 포함되어 있다. 그리고 쿼리 문자열을 가져올 수 있는 query key도 존재한다.

예를 들어 http://localhost:3000/post/1?str=135135을 검색하여 페이지 이동을 하게되면 params에는 { id: '1' } 그리고 query에는 { str: '135135', id: '1' }이 담겨지게 된다.
그래서 위의 코드에서 context. query를 통해 id 값을 가져올 수 있었던 것이다.

그 밖에도 다양한 key값이 존재하는데 https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props 를 참고하면 좋을 것 같다.

SSG vs SSR

그렇다면 어떤 상황에서 SSG를 사용하고 SSR을 사용해야 할지 궁금할텐데 공식문서에서는 자주 변경될 여지가 있는 데이터를 요청하는 경우가 아니면 가능한 SSG를 사용하는 것을 추천한다고 한다.


Reference

0개의 댓글