Pages and Layouts
May 28, 2024
NEXT JS
App Route
Routing
NEXT JS 공식문서를 참고하여 번역함.
# Pages and Layouts
이 페이지를 읽기전에
Routing Fundamentals
,Defining Routes
를 읽고 오는걸 추천합니다.
특수 파일인 layout.js
, page.js
, template.js
는 경로
에 대한 UI를 생성할 수 있도록 합니다. 이 페이지는 이러한 특수 파일을 어떻게 그리고 언제 사용하는지 안내합니다.
# Pages
페이지는 경로에 고유한 UI입니다. page.js
파일에서 컴포넌트를 기본으로 내보내면 페이지를 정의할 수 있습니다.
예를 들어, index
페이지를 만들려면 app
디렉토리 안에 page.js
파일을 추가하십시오:
app/page.tsx
// `app/page.tsx` is the UI for the `/` URLexport default function Page() {return <h1>Hello, Home page!</h1>}
그런 다음, 추가 페이지를 만들려면 새 폴더를 생성하고 그 안에 page.js
파일을 추가하십시오. 예를 들어, /dashboard
경로에 대한 페이지를 만들려면 dashboard
라는 새 폴더를 생성하고 그 안에 page.js
파일을 추가하십시오.
app/dashboard/page.tsx
// `app/dashboard/page.tsx` is the UI for the `/dashboard` URLexport default function Page() {return <h1>Hello, Dashboard Page!</h1>}
알아두면 좋은 정보:
- 페이지에는.js
,.jsx
, 또는.tsx
파일 확장자를 사용할 수 있습니다.
- 페이지는 항상route subtree
의leaf
입니다.
- 경로 세그먼트를 공개적으로 접근 가능하게 만들기 위해서는page.js
파일이 필요합니다.
- 페이지는 기본적으로서버 컴포넌트
이지만,클라이언트 컴포넌트
로 설정할 수 있습니다.
- 페이지는 데이터를 가져올 수 있습니다. 자세한 내용은Data Fetching
섹션을 참조하십시오.
# Layouts
레이아웃은 여러 경로 간에 공유되는 UI입니다. 내비게이션 시 레이아웃은 상태를 유지하고, 상호 작용을 유지하며, 다시 렌더링되지 않습니다. 또한 레이아웃은 중첩
될 수 있습니다.
layout.js
파일에서 React 컴포넌트를 기본으로 내보내면 레이아웃을 정의할 수 있습니다. 이 컴포넌트는 렌더링 시 자식 레이아웃(존재하는 경우) 또는 페이지로 채워질 children
prop을 받아야 합니다.
예를 들어, 레이아웃은 /dashboard 및 /dashboard/settings 페이지와 공유됩니다:
app/dashboard/layout.tsx
export default function DashboardLayout({children, // will be a page or nested layout}: {children: React.ReactNode}) {return (<section>{/* Include shared UI here e.g. a header or sidebar */}<nav></nav>{children}</section>)}
Root Layout (Required)
루트 레이아웃은 app
디렉토리의 최상위 수준에 정의되며 모든 경로에 적용됩니다. 이 레이아웃은 필수이며, 서버에서 반환된 초기 HTML을 수정할 수 있도록 html
및 body
태그를 포함해야 합니다.
app/layout.tsx
export default function RootLayout({children,}: {children: React.ReactNode}) {return (<html lang="en"><body>{/* Layout UI */}<main>{children}</main></body></html>)}
Nesting Layouts
기본적으로 폴더 계층 구조의 레이아웃은 중첩되며, 이는 자식 레이아웃을 children
prop을 통해 감싼다는 의미입니다. 특정 경로 세그먼트(폴더) 내에 layout.js
를 추가하여 레이아웃을 중첩할 수 있습니다.
예를 들어, /dashboard
경로에 대한 레이아웃을 만들려면, dashboard
폴더 안에 새로운 layout.js
파일을 추가하세요:
app/dashboard/layout.tsx
export default function DashboardLayout({children,}: {children: React.ReactNode}) {return <section>{children}</section>}
위의 두 레이아웃을 결합하면, 루트 레이아웃(app/layout.js
)이 대시보드 레이아웃(app/dashboard/layout.js
)을 감싸고, 이는 app/dashboard/*
내부의 경로 세그먼트를 감싸게 됩니다.
두 레이아웃은 다음과 같이 중첩됩니다:
알아두면 좋은 정보:
-.js
,.jsx
, 또는.tsx
파일 확장자는 레이아웃에 사용할 수 있습니다.
- 오직 루트 레이아웃만<html>
및<body>
태그를 포함할 수 있습니다.
-layout.js
와page.js
파일이 동일한 폴더에 정의되어 있을 때, 레이아웃이 페이지를 감싸게 됩니다.
- 레이아웃은 기본적으로서버 컴포넌트
이지만클라이언트 컴포넌트
로 설정할 수 있습니다.
- 레이아웃은 데이터를 가져올 수 있습니다. 자세한 내용은Data Fetching
섹션을 참조하세요.
- 부모 레이아웃과 자식 간에 데이터를 전달하는 것은 불가능합니다. 하지만 경로 내에서 동일한 데이터를 여러 번 가져올 수 있으며, React는 성능에 영향을 주지 않고요청을 자동으로 중복 제거
합니다.
- 레이아웃은 자신 아래의 경로 세그먼트에 접근할 수 없습니다. 모든 경로 세그먼트에 접근하려면, 클라이언트 컴포넌트에서useSelectedLayoutSegment
또는useSelectedLayoutSegments
를 사용할 수 있습니다.
- 특정 경로 세그먼트를 공유 레이아웃에 포함하거나 제외하려면Route Groups
을 사용할 수 있습니다.
-Route Groups
을 사용하여 여러 루트 레이아웃을 만들 수 있습니다. 예시는여기
를 참조하세요.
-pages
디렉터리에서 마이그레이션하기: 루트 레이아웃이_app.js
및_document.js
파일을 대체합니다.마이그레이션 가이드
를 참조하세요.
# Templates
템플릿은 자식 레이아웃이나 페이지를 감싼다는 점에서 레이아웃과 유사합니다. 경로 간에 상태를 유지하며 지속되는 레이아웃과 달리, 템플릿은 탐색 시 각 자식에 대해 새 인스턴스를 생성합니다. 이는 사용자가 템플릿을 공유하는 경로 간을 탐색할 때마다 컴포넌트의 새 인스턴스가 마운트되고, DOM 요소가 재생성되며, 상태가 유지되지 않고, 효과가 다시 동기화된다는 것을 의미합니다.
특정 동작이 필요한 경우 템플릿이 레이아웃보다 더 적합한 선택이 될 수 있습니다. 예시:
useEffect
(예: 페이지 조회수 기록) 및useState
(예: 페이지별 피드백 form)에 의존하는 기능.- 기본 프레임워크 동작을 변경하기 위해서입니다. 예를 들어, 레이아웃 내부의 Suspense 경계는 레이아웃이 처음 로드될 때만 대체 콘텐츠를 표시하고 페이지 전환 시에는 표시하지 않습니다. 반면에 템플릿의 경우에는 각 탐색 시마다 대체 콘텐츠가 표시됩니다.
템플릿은 template.js
파일에서 기본 React 컴포넌트를 내보내어 정의할 수 있습니다. 이 컴포넌트는 children
prop을 받아야 합니다.
app/template.tsx
export default function Template({ children }: { children: React.ReactNode }) {return <div>{children}</div>}
중첩 관점에서 template.js
는 레이아웃과 그 자식 사이에 렌더링됩니다. 다음은 간단한 출력 예시입니다:
Output
<Layout>{/* Note that the template is given a unique key. */}<Template key={routeParam}>{children}</Template></Layout>
# Metadata
app
디렉토리에서 Metadata API
를 사용하여 title
및 meta
와 같은 <head>
HTML 요소를 수정할 수 있습니다.
메타데이터는 layout.js
또는 page.js
파일에서 metadata 객체
또는 generateMetadata 함수
를 내보내어 정의할 수 있습니다.
app/page.tsx
import { Metadata } from 'next'export const metadata: Metadata = {title: 'Next.js',}export default function Page() {return '...'}
알아두면 좋은 정보: 루트 레이아웃에
<title>
및<meta>
와 같은<head>
태그를 수동으로 추가하지 말아야 합니다. 대신,Metadata API
를 사용하여 스트리밍 및<head>
요소의 중복 제거와 같은 고급 요구 사항을 자동으로 처리해야 합니다.
API reference
에서 사용 가능한 메타데이터 옵션에 대해 자세히 알아보세요.