Next.js 에서는 react-router-dom 과 같이 개발자가 직접 라우팅 설정을 하지 않아도 된다.
대신에 hook과 파일 컨벤션을 통해 라우팅을 지원하고 있다.
또한 Next.js는 v13 부터 app 라우팅을 지원하는데 이전에 pages 라우팅 부터 먼저 살펴보자.
Next.js pages routing
src/pages
├── _app.tsx
├── index.tsx
├── naver.tsx
├── preview.tsx
├── profile
│ ├── [name].tsx
│ └── index.tsx
│ └── phone.tsx
└── setting
├── auto-complete.tsx
├── [...search].tsx
└── site.tsx
Next.js 는 /pages or /src/pages 폴더내의 폴더명 및 파일명에 맞춰 자동으로 라우팅된다.
(/src/pages 가 존재하면 /page 는 무시됨.)
위의 예시를 보면 정적 라우팅의 경우 /profile, /profile/phone 으로 정의된다.
동적라우팅의 경우 파일명이나 폴더명을 []로 감싸주면 된다.
/profile/sooni 로 이동했다면 [name].tsx 컴포넌트가 렌더링되며, "sooni"라는 값을 받아올 수 있다.
Catch-All 라우팅의 경우 파일명이나 폴더명을 [...]로 감싸주면 된다.
/setting/cloud/star/sun 로 이동했다면 [...search].tsx 컴포넌트가 렌더링되며,
segment로 넘겨받은 "cloud", "star", "sun" 이라는 값을 받아올 수 있다.
Optional Catch-all Segments 라우팅의 경우 파일명이나 폴더명을 [[...]] 로 감싸주면 된다.
src/app
├── layout.tsx
├── page.tsx
├── blog
│ └── [[...slug]].tsx
└── cafe
└── [[...slug]].tsx
[...slug]: catch-all 경로는 잡아내지 못한다.
$ localhost:3000/blog - 404 not found
$ localhost:3000/blog/efsd/2301/gee - success
[[...slug]]: catch-all 경로까지 잡아낸다.
$ localhost:3000/cafe - success
$ localhost:3000/cafe/efsd/2301/gee - success
Next.js app routing
Next.js v13 부터 React Server Components 가 내장된 App Router 를 지원한다. App Router는 layout을 공유할 수 있고, 라우팅 중첩, 로딩 상태, 에러 핸들린 등을 지원한다.
App Router는 app 디렉토리 안에서 동작한다. 기본적으로 app 디렉토리 내부의 컴포넌트는 React Server Component 이다.
File Conventions
- page.js: 접근 가능한 경로를 만들고 라우터의 유니크한 UI를 만든다.
- route.js: 라우트의 server-side API endpoints 를 만든다.
- layout.js: 여러 페이지에서 공통으로 사용되는 전체적인 디자인 및 구조를 나타내는 UI이다. layout은 중첩될 수 있으며 리렌더링되지 않는다.
- template.js: 템플릿은 각 자식 레이아웃이나 페이지를 래핑하는 점에서 레이아웃과 유사하다. 그러나 레이아웃은 라우트 간에 지속되며 상태를 유지하는 반면, 템플릿은 네비게이션 시에 각 자식에 대해 새로운 인스턴스를 생성한다. 이는 사용자가 템플릿을 공유하는 라우트 간에 이동할 때 해당 컴포넌트의 새 인스턴스가 마운트되고, DOM 요소가 다시 생성되며 상태가 보존되지 않으며 효과가 다시 동기화된다는 것을 의미한다.
- loading.js: loading.js는 page또는 자식 segment를 React Suspense Boundary로 감싸면 그들이 로드상태일때 loading UI를 보여준다.
- error.js: error.js는 page또는 자식 segment를 React Error Boundary로 감싸고 error가 잡히면 error UI를 보여준다.
- global-error.js: error.js 와 비슷하지만, 특히 루트 레이아웃.js 의 오류를 포착하기 위한 것이다.
- not-found.js: route segment 나 URL 이 어떠한 route 와도 매치되지 않으면 보여줄 UI 이다.
Component Hierarchy
Layouts
layout UI는 page 간에 공유된다. 네비게이션을 할 때, layout은 상태를 보존하며, 리렌더하지 않는다. 또한 중첩이 가능하다.
Tip!
- 맨 위의 레이아웃을 루트 레이아웃이라고 한다. 루트 레이아웃은 필수이며, 앱의 모든 페이지에서 공유된다. 루트 레이아웃에는 HTML 및 본문태그가 포함되어야 한다.
- route segment 마다 그들만의 layout 을 설정할 수 있다. 이 layout 들은 해당 segment안에서 공유된다.
- layout 들을 data를 fetch 할 수 있다.
- 부모레이아웃과 자식 레이아웃 간에 데이터를 전달할 수 없다. 그러나 라우터에서 동일한 데이터를 두번 이상 가져올 수 있으며, React 성능에는 영향을 주지 않으며 자동 중복 제거한다.
- 레이아웃이 현재 경로 세그먼트에 접근할 수 없다. 경로 세그먼트에 접근하려면 클라이언트 컴포넌트에서 Selected Layout Segment 를 사용한다.
- root layout은 기본적으로 Server Component 이지만, Client Component로 사용할 수 없다.
Root Layout (Required)
root layout은 app 디렉토리의 최상위에 정의되며, 모든 경로에 적용된다. 이로 초기 서버로부터 받는 HTML을 수정할 수 있다.
Tip!
- app 디렉토리는 반드시 root layout을 포함해야 한다.
- root layout은 반드시 html 과 body 태그를 정의해야한다.
- built-in SEO support를 사용해 head HTML 요소를 관리할 수 있다.
- root layout은 기본적으로 Server Component 이지만, Client Component로 사용할 수 없다.
Templates
layout과 비슷하다. 여러 경로에 걸쳐 상태를 유지하는 레이아웃과 달리 검색중인 각 자식에 대해 새 인스턴스를 만든다.
즉, 사용자가 segment 안에서 경로를 이동 할 때, 컴포넌트의 새 인스턴스가 마운트되고, DOM 요소가 다시 생성되고 상태가 보존되지않으며, 다시 동기화 된다.
특별한 이유가 없다면 layouts을 사용하는 것 을 권하지만, 다음과 같은 경우 레이아웃보다 템플릿이 더 적절한 선택일 수 있다.
- useEffect에 의존하는 기능(예: 페이지 뷰 기록) 및 useState(예: 페이지별 피드백 폼) 등.
- 기본 프레임워크 동작을 변경해야 할 때. 예를 들어, 레이아웃 내의 Suspense 경계는 레이아웃이 처음 로드될 때에만 대체 콘텐츠를 표시하고 페이지 전환 시에는 표시하지 않는다. 반면에 템플릿의 경우 각 네비게이션에서 대체 콘텐츠가 표시된다.
Modifying head
루트 레이아웃에 title 및 meta와 같은 head 태그를 수동으로 추가하면 안된다. 대신 스트리밍 및 <헤드> 요소 중복 제거와 같은 고급 요구사항을 자동으로 처리하는 메타데이터 API 를 사용해야 한다.
'React > Next.js' 카테고리의 다른 글
[Next.js] Route System - 3) next/route useRouter (2) | 2023.12.05 |
---|---|
[Next.js] Route System - 2) next/link - Link (0) | 2023.12.05 |
[Next.js] Server Components (0) | 2023.12.04 |
[Next.js] SSR, SSG, ISR (0) | 2023.12.04 |
[Next.js] SSR과 CSR의 차이 (1) | 2023.12.04 |
댓글