본문 바로가기
스터디

[Next.js] Dynamic Routes(동적 경로)

by rious275 2023. 9. 26.

Dynamic Routes

정해지지 않은 동적 데이터를 세그먼트로 사용하려는 경우, 요청 시 채워지거나 빌드 시 미리 렌더링되는 동적 라우팅을 사용할 수 있다.

동적 세그먼트는 이름을 대괄호로 묶어 만들 수 있다. 이 세그먼트는 layout, page, routegenerateMetadata(메타데이터 함수)에 매개변수로 전달된다.

Example(예제)

예를 들어 app/blog/[slug]/page.js에서 [slug]는 동적 세그먼트이며, 아래와 같이 매개변수로 전달된다.

type PageTypes = { params: { slug: string } };

const Page = ({ params }: PageTypes) => {
  return <div>My Post: {params.slug}</div>;
};

Generating Static Params(정적 매개변수 생성)

generateStaticParams 함수는 동적 세그먼트와 함께 사용하며 요청 시 빌드 시점에 경로를 정적으로 생성한다.

const generateStaticParams = async () => {
  const posts = await fetch(url).then(res => res.json());

  return posts.map(post => ({
    slug: post.slug,
  }));
};

generateStaticParams 함수의 가장 큰 장점은 데이터를 스마트하게 검색할 수 있다는 점이다. fetchgenerateStaticParams 함수 내에서 콘텐츠를 가져오면 요청이 자동으로 메모화된다.

즉, 여러 generateStaticParams를 사용할 때 레이아웃 및 페이지에 걸쳐 같은 인수가 포함되면 fetch는 한 번만 실행하고, 빌드 시간이 단축된다.

Catch-all Segments

동적 세그먼트는 괄호 안의 [...folderName] 안에 줄임표를 추가하여 캐치올 세그먼트로 확장할 수 있다. 쉽게 말해 기존에 동적 세그먼트는 app/shop/1, app/shop/2와 같이 한 단계의 변수이며 그 이상의 단계 확장까지는 하지 못한다.

하지만 Catch-all 세그먼트는 확장까지 가능하다는 뜻이다. 예를 들어, app/shop/[...slug]/page.js/shop/clothes뿐만 아니라 /shop/clothes/tops, /shop/clothes/tops/t-shirts 등과도 일치한다.

Optional Catch-all Segments

캐치올 세그먼트는 [[...folderName]]처럼 매개 변수를 이중 대괄호 안에 포함하여 옵셔널하게 만들 수 있다. 쉽게 말해서, 선택적 캐치올 세그먼트는 매개변수가 없는 경로도 일치한다는 점이다.

예를 들어, app/shop/[[...slug]]/page.js/shop/clothes, /shop/clothes/tops, /shop/clothes/tops/t-shirts 외에 /shop과도 일치한다.

Typescript

타입스크립트를 사용하는 경우, 구성된 경로 세그먼트에 따라 매개변수에 대한 유형을 추가할 수 있다.

type PageTypes = { params: { slug: string } };

const Page = ({ params }: PageTypes) => {
  return <h1>My Page</h1>;
};