[Next] Data Fetching

안승찬·2024년 3월 30일

Next

목록 보기
3/4

본 게시물은 Next 에서의 Data Fetching에 대해서 다루고 있다.

getStaticProps

getStaticProps를 사용하게 되면, Next.js는 getStaticProps를 사용하여 리턴된 props를 이용하여 페이지를 빌드 타임에 pre-render한다.

	export async function getStaticProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  }
}

언제 사용해야 될까??

  • 유저의 요청 전에 페이지를 빌드 타임에 미리 랜더해도 되는 페이지
  • getStaticProps 함수는 HTML과 JSON파일을 만들어 서버로부터 매우 빠르게 정보를 받아올 수 있다.

Server-side code를 직접적으로 작성할 수 있다.

// 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를 이용하는 것이다.

ISR 이용하기(Incremental Static Regenration)

export async function getStaticProps() {
  const delayInSeconds =2;
  const data = await new Promise((reslove)=> setTimeout(()=> resolove(Math.random()),delayInSeconds * 1000));
  
  
 return {
  props: {data},
  revalidate: 5,
 }
  
}
  • 처음 요청으로부터 5초 동안 데이터가 캐시된 상태로 존재하여 보여진다.
  • 5초 이후, 다음 리퀘스트가 stale 상태로 페이지에 적용될 것이다.
  • Next.js 트리거가 페이지를 background에서 만든다.
  • 페이지가 성공적으로 만들어지게 되면, Next.js는 캐시가 유효한지 아닌지 판단한다. 이후, 새롭게 업데이트 된 페이지를 보여주게 된다.

Link를 이용하여 라우팅 처리 하기

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

getServerSideProps는 getStaticProps와 비슷하지만, 서버 사이드 렌더링을 위한 함수이다. 요청이 들어올 때마다 호출되고, 그 때마다 사전 렌더링을 진행한다.
getStaticProps와는 다르게 요청이 들어올 때마다 호출되기에 빌드 이후 자주 바뀌는 동적 데이터가 들어갈 때 사용하기 좋다

Example

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 },
  };
};

0개의 댓글