Next.js 12 → Next.js 13 달라진 점 (App router, Data fetching)

지은·2023년 7월 14일
8

1. Page Router → App Router

Next.js 12에서는 pages 디렉토리를 최상위 디렉토리로 가지고, 그 안에 파일들의 이름으로 url이 자동으로 라우팅되었다.

Next.js에서는 app 디렉토리를 최상위 디렉토리로 가지고, 모든 파일들이 자동으로 라우팅되는 것이 아니라, 폴더 안에 page.jsroute.js라는 파일명을 가진 파일들만 라우팅된다.

Colocation - Next.js


2. Data Fetching 방식 변경

Next.13부터는 getServerSideProps, getStaticProps, getStaticPaths 등의 서버 사이드 API가 더 이상 사용되지 않는다.

Next.js 13으로 만든 블로그에서 getStaticProps() 함수를 사용하고 빌드했더니 컴파일 중에 다음과 같은 에러가 발생했다.

Failed to compile.

./src/app/posts/[postId]/page.tsx
ReactServerComponentsError:

"getStaticProps" is not supported in app/. Read more: https://nextjs.org/docs/app/building-your-application/data-fetching

Next.js 13의 앱 라우터에서는 getStaticProps를 지원하지 않는다는 뜻이다.
에러에서 알려준 공식 문서 사이트에 들어가니 아래의 내용을 발견할 수 있었다.

Data Fetching - Next.js

The new data fetching in Next.js 13 is built on top of the fetch() Web API and akes use of async / await in Server Components.

Now, instead of using getServerSideProps() and getStaticProps()all fetched data is static by default, meaning it's rendered at build time.

Next.js 13에서 데이터를 가져오는 새로운 방식은 fetch 웹 API 위에 구축되었고, 서버 컴포넌트에서 async/await을 사용합니다.

이제 getServerSidePropsgetStaticProps를 사용하는 대신, 가져온 모든 데이터는 기본적으로 정적이며, 빌드 시에 렌더링됩니다.
(빌드 시에 렌더링하면 실시간으로 변경되는 데이터들은 데이터를 업데이트 못하지 않나?)

However, Next.js extends the fetch options object to allow each request to set its own caching and revalidating rules.

With the {next: revalidate} option, you are able to refresh any piece of your static data, either at a set interval or when that piece changes in your backend.

For dynamic data that changes often or is specific to users, you can pass the {cache: no-store} option in the fetch request.

그래서 Next.js는 fetch 옵션 객체를 확장해서 각 요청마다 자체 캐싱 및 재검증 규칙을 설정할 수 있도록 했습니다.

{next: revalidate} 옵션을 사용하면, 정적인 데이터를 설정된 간격으로 새로고침하거나 백엔드에서 변경이 있을 때마다 새로고침 할 수 있습니다.

자주 변경되는 데이터나 사용자와 관련된 동적인 데이터의 경우, fetch 요청 시에 {cache: no-store} 옵션을 사용할 수 있습니다.

➡️ 정리하면, 이전에 쓰던 서버 사이드 API 대신에 fetch()를 사용하면 되고, fetch의 옵션 객체를 이용해 이전의 서버 사이드 API와 같은 기능을 하게 할 수 있다.

  • { cache: 'force-cache' } : 캐시를 강제한다는 뜻으로 정적 사이트로 만든다. (getStaticProps 대체)
  • next: { revalidate: 10 } : 10초마다 캐시를 갱신한다는 뜻으로 10초 후에 새로운 요청이 오면 페이지를 새로 생성한다. (revalidate 옵션이 있는 getStaticProps 대체[ISR])
  • { cache: 'no-store' } : 모든 요청에서 최신 데이터를 받아온다. 즉, 항상 서버 사이드 렌더링한다. (getServerSideProps 대체)

generateStaticParams

: 동적 세그먼트를 사용해 정적으로 라우트(경로)를 생성하는 함수
Next.js 12에서의 getStaticPaths와 같은 역할을 하는 함수라고 보면 된다. 사용법도 비슷하지만 return문이 조금 더 간결해졌다!

generateStaticParams - Next.js

posts/[postId]/page.tsx

export function generateStaticParams() {
  const posts = getSortedPostsData(); // 내림차순으로 정렬한 모든 게시글을 불러와서

  if (!posts) return [];

  return posts.map((post) => ({ // postId 값을 가진 객체를 담은 배열을 리턴
    postId: post.id,
  }));
}

generateMetatdata

: 동적인 메타데이터를 생성하여 Metadata 객체를 리턴하는 함수

generateMetatdata - Next.js

posts/[postId]/page.tsx

export async function generateMetadata({ params }: Props) {
  const { postId } = params; // 동적인 값 postId에 따라
  const post = await getPostData(postId); // 게시글(post) 데이터를 불러오고

  if (!post) {
    return {
      title: 'Post Not Found',
    };
  }

  return {
    title: post.title, // 메타데이터 객체에 title 값을 담아 리턴한다.
  };
}

게시글 페이지를 로드하면 아래처럼 게시글마다 다른 title을 가지고 있는 것을 확인할 수 있다.

profile
개발 공부 기록 블로그

4개의 댓글

comment-user-thumbnail
2023년 7월 16일

어후 어렵네요 ㅋㅋ ㅠ 화이팅입니다

답글 달기
comment-user-thumbnail
2023년 7월 16일

저도 열심히 해보겠습니다 허허

답글 달기
comment-user-thumbnail
2023년 7월 16일

은근 많은 것들이 바뀌었군요..! 고생하셨습니당

답글 달기
comment-user-thumbnail
2023년 7월 16일

저는 13 해보긴했는데 버전이 낮아서 아직 강제성이 없는데,,
이거보니까 무섭네요 ㅎㅎ 이거말고도 이것저것 많던데 고생하셨습니다!

답글 달기