목차


일반 fetch() vs Next.js fetch()


Next.js에서는 fetch()함수로 데이터를 통신하는 것을 권장한다. 이 이유는 Next.js 기존 fetch의 확장판으로 커스텀 했기 때문이다. 일반 fetch와는 다르게 Next.js의 fetch()는 캐싱 및 성능 최적화 기능을 더해준다. 어떠한 기능이 있는지 살펴보자.

Next.js에서 fetch를 logging하는 법


/** @type {import('next').NextConfig} */
const nextConfig = {
  logging: {
    fetches: {
      fullUrl: true,
    },
  },
};

export default nextConfig;

next.config.mjs파일에 위와 같이 logging옵션을 추가해 주면 터미널에서 확인 할 수 있다.

Next.js의 fetch() 옵션


cache할 경우

const data = await fetch('https://api.vercel.app/blog', { cache: 'force-cach' })

요청의 결과를 저장하는 옵션이다. 첫 요청을 제외하고는 위와 같이 fetch()가 있어도 통신을 하지 않고 저장된 데이터 값을 가져온다. 거의 변하지 않는 데이터를 렌더링할 때 사용하면 좋은 옵션이다.

cache하지 않는 경우

const data = await fetch('https://api.vercel.app/blog', { cache: 'no-store' })

요청의 결과를 저장하지 않는 옵션이다. { cache: 'no-store' }를 두번째 인자에 넣어주면 된다. 이러면 페이지 진입할 때마다 fetch()를 진행한다. 실시간성 데이터가 렌더링 될 때 사용하면 적합한 옵션이다.
옵션의 기본 값으로 옵션에 아무런 설정을 하지 않으면 { cache: 'no-store' }처럼 동작한다.
(* v15이전 버전은 캐싱하는 것을 기본으로 설정되었으나 사용자가의 불만이 많아 v15부터는 캐싱하지 않는 것이 default이다.)

특정 시간 이후에 다시 fetch

const data = await fetch('https://api.vercel.app/blog', { next: { revalidate: 3 } })

Page-Router의 ISR과 같이 특정 시간을 주기로 캐시를 업데이트 하는 방식이다. 가끔 데이터가 업데이트 될 때 사용하면 적합한 옵션이다. revalidate안에 들어갈 숫자는 초단위이다.

특정 요청이 들어 왔을 때에 다시 fetch

const data = await fetch('https://api.vercel.app/blog', { next: { tags: ['a']}})

Page-Router의 On-Demand ISR과 비슷한 방식이다. 처음 요청 시 데이터를 캐시하고, 특정 요청 시 있을 때 갈아끼우는 형식이다. 가끔 변하는 데이터를 핸들링할 때 편리한 옵션이다.

Request Memoization


Next.js에는 여러 컴포넌트의 모음이다. 만약 각 컴포넌트에 동일 fetch가 있다고 가정하면 어떻게 될까?

const AComponent = () => {
  const data = await fetch('https://api.vercel.app/blog', { cache: 'no-store' })
  // ...
}

const BComponent = () => {
  const data = await fetch('https://api.vercel.app/blog', { cache: 'no-store' })
  // ...
}

const CComponent = () => {
  const data = await fetch('https://api.vercel.app/blog', { cache: 'no-store' })
  // ...
}

const Page = () => {
  return (
    <>
      <AComponent/>
      <BComponent/>
      <CComponent/>
    </>
  )
}

Next.js에서는 이러한 경우 모든 fetch를 요청하는 것이 아닌 하나의 요청만 캐시하고 나머지는 캐시된 데이터를 전달한다. 이것은 위에서 보았던 fetch의 캐시 영역이랑은 조금 별개의 영역이다. fetch()에서 제공하는 것이 아닌 Next.js에서 제공해주는 최적화이다.
이렇게 렌더링이 끝나면 fetch cache와는 다르게 데이터는 보관하지 않고 사라진다.