본문 바로가기

개발 공부/React

Next.js - 동적 라우팅

동적 라우팅

동적 라우팅이란 URL 경로 중 동적으로 변하는 값을 처리할 수 있도록 만든 라우팅 방식입니다.

예를 들어,

/dashboard/invoices/123/edit
  • 여기서 123은 고정된 경로가 아닌 인보이스 ID입니다.
  • 이처럼 매번 달라질 수 있는 값에 대응하기 위해, 디렉토리 이름을 [] 대괄호로 감싸면 Next.js는 해당 경로를 동적 파라미터로 인식합니다.

 

 

invoices/
└── [id]/      # ← 이게 동적 세그먼트
    └── edit/
        └── page.tsx
  • 이 구조는 아래와 같은 모든 경로를 처리할 수 있습니다
    • /dashboard/invoices/123/edit
    • /dashboard/invoices/456/edit
    • /dashboard/invoices/any-value/edit

이렇게 하나의 구조로 다양한 인보이스를 편집할 수 있습니다.

 

내부 동작 방식

[id]라는 폴더명은 Next.js에 다음을 의미합니다:

"이 자리에 어떤 문자열이든 올 수 있고, 그 문자열을 params.id로 전달하겠다."

 

따라서 page.tsx에서는 이렇게 받습니다.

export default function Page({ params }: { params: { id: string } }) {
  const id = params.id;
}

 

  • 이때 params.id의 타입은 string
  • URL 경로의 :id 부분이 자동으로 여기에 들어감

 

[id]/edit의 의미

이 구조는 단순히 [id] 하나만 쓰는 것보다 한 단계 더 세분화된 UI 흐름을 만듭니다.

invoices/
├── [id]/
│   ├── page.tsx        # ← 상세 페이지
│   └── edit/
│       └── page.tsx    # ← 편집 페이지 (중첩)

 

  • /dashboard/invoices/123
    • 123번 인보이스 상세 조회
  • /dashboard/invoices/123/edit
    • 123번 인보이스 편집 페이지

즉, [id]를 기준으로 하위 경로까지 자유롭게 구성할 수 있고, 이게 바로 중첩된 동적 라우팅입니다

 


예시

디렉토리 구조

app/
└── dashboard/
    └── invoices/
        └── [id]/
            └── edit/
                ├── page.tsx        ← 핵심
                ├── not-found.tsx   ← 존재하지 않는 ID 대응
                └── edit-form.tsx   ← 수정 폼 컴포넌트

.

 

URL 접근 방식

해당 페이지는 다음과 같은 URL을 통해 접근됩니다

/dashboard/invoices/123/edit
  • 여기서 123은 동적으로 변하는 인보이스 ID이며, [id] 디렉토리에 대응됩니다.
  • 이 구조를 통해 각 인보이스를 식별하고, 수정할 수 있도록 라우팅이 구성됩니다.

 

page.tsx 

import Form from "@/app/ui/invoices/edit-form";
import Breadcrumbs from "@/app/ui/invoices/breadcrumbs";
import { fetchInvoiceById, fetchCustomers } from "@/app/lib/data";
import { notFound } from "next/navigation";

export default async function Page(props: { params: Promise<{ id: string }> }) {
  const params = await props.params;
  const id = params.id;

  const [invoice, customers] = await Promise.all([
    fetchInvoiceById(id),
    fetchCustomers(),
  ]);

  if (!invoice) {
    notFound();
  }

  return (
    <main>
      <Breadcrumbs
        breadcrumbs={[
          { label: "Invoices", href: "/dashboard/invoices" },
          {
            label: "Edit Invoice",
            href: `/dashboard/invoices/${id}/edit`,
            active: true,
          },
        ]}
      />
      <Form invoice={invoice} customers={customers} />
    </main>
  );
}
  1. params에서 동적으로 들어온 id 값을 추출
  2. fetchInvoiceById(id)로 해당 인보이스 데이터를 불러옴
  3. fetchCustomers()로 고객 목록 데이터도 같이 불러옴
  4. 인보이스가 존재하지 않으면 notFound()를 통해 404 처리
  5. 데이터를 기반으로 Form 컴포넌트와 Breadcrumbs를 렌더링

 

 

'개발 공부 > React' 카테고리의 다른 글

React Query, Redux Toolkit Query  (0) 2025.06.22
TanStack Query  (0) 2025.05.22
Next.js - layout.tsx, children  (0) 2025.05.11
Next.js- cookies().get(), middleware 로그인 유지  (0) 2025.05.09
Next.js, Redux - 로그인/로그아웃  (0) 2025.05.06