Defining Routes
1️⃣ 경로 생성
- 폴더를 사용하여 경로를 정의하는 파일 시스템 기반 라우터를 사용한다.
- 각 폴더는 URL 세그먼트에 매핑되는 경로 세그먼트를 나타낸다.
- page 파일이 없는 폴더는 공개적으로 액세스할 수 없다.
2️⃣ UI 만들기
NextJS 공식문서 파헤치기(1) 에서 알아보았던 파일 컨벤션에 따라 각 경로 세그먼트에 대하여 UI를 만들 수 있다.
// app/page.tsx
// 각 폴더에 page 파일을 사용하여 해당 폴더 라우트에 액세스할 수 있게 해준다.
export default function Page() {
return <h1>Hello, Next.js!</h1>
}
Pages
page.js
는 경로에 고유한 UI 이다.- 컴포넌트를 내보내는 페이지를 정의할 수 있다.
- ex) index 페이지를 생성하고 싶다면 app 폴더의 내에서 page.js를 생성하면 index.js 와 같은 역할을 한다.
// 아래의 예제에는 내보내는 컴포넌트 이름이 `Page`라고 되어있지만
// `npx create-next-app@latest`를 하여 초기 앱을 만들었을 때 '/' 경로의 page.tsx가 `Home`으로 되어있는 걸 보면
// 각 페이지의 경로 이름을 넣는것이 더 좋을것 같다.
// app/page.tsx 는 '/' URL의 UI 이다.
export default function Page() {
return <h1>Hello, Home page!</h1>
}
// app/dashboard/page.tsx 는 '/dashboard' URL의 UI 이다.
export default function Page() {
return <h1>Hello, Dashboard Page!</h1>
}
Layouts and Templates
1️⃣ 레이아웃
- 여러 경로 간에 공유되는 UI
- 레이아웃은 상태를 보존하고, 상호작용 하며, 다시 렌더링하지 않는다.
- 레이아웃은 중첩 가능하다.
- ex)
/dashboard
에 레이아웃을 두면/dashboard/settings
와 같은 하위 페이지들에서도 레이아웃이 공유된다.
2️⃣ 루트 레이아웃(필수)
- app 디렉토리 최상위 수준에서 적용되며 모든 경로에서 적용된다.
- 루트 레이아웃은
html
,body
태그를 포함해야 하며 필수로 작성되어야한다. (루트 레이아웃만hmtl
,body
태그를 작성할 수 있음) - 서버에서 반환된 초기 HTML을 수정 가능
- font, globalcss, meta 데이터 등등 의 정보가 들어갈 수 있다.
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{/* Layout UI */}
<main>{children}</main>
</body>
</html>
)
}
3️⃣ 중첩 레이아웃
- 폴더 계층의 레이아웃은 중첩 되어있다.
- 특정 경로 세그먼트(폴더) 내부에
children
을 추가하여 레이아웃을 중첩할 수 있다.
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
4️⃣ 템플릿
- 자식 레이아웃이나 페이지를 래핑한다는 점에서 레이아웃과 유사하다.
- 탐색 시 각 자식에 대해 새 인스턴스를 만든다. (경로 간에 지속되고 상태를 유지하는 레이아웃과의 차이점)
- 따라서 템플릿을 공유하는 경로 사이를 탐색할 때 자식의 새 인스턴스가 마운트되고 DOM 요소가 다시 생성되고 클라이언트 컴포넌트의 상태가 보존되지 않는다. (리렌더링 된다)
- 레이아웃보다 템플리이 더 적합할 때
- 탐색을 다시 동기화
- 탐색 시 자식 클라이언트 구성요소의 상태를 재설정
- 템플릿은
template.js
파일에서 기본 리액트 컴포넌트를 내보내어 정의할 수 있다. (컴포넌트는 children prop을 허용해야 함)
// app/template.tsx
export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}
// 중첩의 관점에서 template.js는 레이아웃과 children 사이에 위치한다.
// 아래는 단순화된 출력 형식
<Layout>
{/* Note that the template is given a unique key. */}
<Template key={routeParam}>{children}</Template>
</Layout>
5️⃣ 예시
- 메타데이터 API를 사용하여 HTML
<head>
,<title>
,<meta>
요소 등을 수정할 수 있다. - 메타데이터는
layout.js
,page.js
파일에서metadata
객체나generateMetadata
함수를 통해 정의할 수 있다.
// app/page.tsx or app/layout.tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js',
}
export default function Page() {
return '...'
}
✅ 알아두면 좋은 정보
- 같은 폴더 내에 layout.js 와 page.js 가 함께 존재하게 된다면 layout이 page를 래핑한다.
- 기본적으로 서버 컴포넌트이지만 클라이언트 컴포넌트로 설정 가능하다.
- 부모 레이아웃과 자식 레이아웃간에 데이터 전달은 불가능하다. 하지만 한 경로에서 동일한 데이터를 두 번 이상 가져올 수 있으며, 리액트는 성능에 영향을 주지않고 자동적으로 중복된 요청을 제거한다.
pathname
에 액세스할 수 없다. 하지만 가져온 클라이언트 컴포넌트는usePathname
hook을 사용하여 경로 이름에 액세스할 수 있다.- 레이아웃은 그 자체 아래의 경로 세그먼트에 액세스할 수 없다. 모든 경로 세그먼트에 액세스하려면 클라이언트 컴포넌트에서
useSelectedLayoutSegment
,useSelectedLayoutSegments
를 사용해야한다. - Route Group을 사용하면 공유 레이아웃에서 특정 경로 구간을 선택하거나 제외할 수 있다.
- Route Groups를 사용하여 여러 루트 레이아웃을 만들 수 있다.
- 폴더 이름을
(folderName)
형식으로 만들면 Route Group을 사용할 수 있다. - 루트 레이아웃은 NextJS 12버전 page router의
_app.js
,_document.js
파일을 대체할 수 있다. - 루트 레이아웃에 태그를 수동으로 추가하면 안된다. 대신 스트리밍 및 중복 제거 요소와 같은 고급 요구 사항을 자동으로 처리하는 Metadata API를 사용해야 한다.
📚 REFERENCE
'FE > NextJS' 카테고리의 다른 글
NextJS 공식문서 파헤치기 (Middleware) (1) | 2024.12.17 |
---|---|
NextJS 공식문서 파헤치기 (Error Handling) (0) | 2024.12.10 |
NextJS 공식문서 파헤치기 (Caching) (1) | 2024.11.15 |
NextJS 공식문서 파헤치기 (Linking and Navigating) (5) | 2024.11.14 |
NextJS 공식문서 파헤치기 (Routing Fundamentals) (1) | 2024.11.13 |