Routing - 페이지와 레이아웃

Zense·2023년 8월 14일
0

Next.js Docs 번역

목록 보기
7/14
post-custom-banner

페이지와 레이아웃

Next.js 13의 app 라우터에서는 페이지, 공유 레이아웃, 템플릿을 쉽게 생성할 수 있는 새로운 파일 규칙을 도입했습니다. 이 페이지에서는 Next.js 애플리케이션에서 이러한 특수 파일을 어떻게 사용하는지 설명합니다.

페이지

페이지는 경로에 고유한 UI입니다. page.js 파일에서 컴포넌트를 export 해서 페이지를 정의할 수 있습니다. 폴더를 중첩시켜 경로를 정의하고 page.js 파일을 추가해 공개적으로 접근 가능하도록 만듭니다.

app 디렉토리 내에 page.js 파일을 추가하여 첫 번째 페이지를 만듭니다.

/* app/page.js */

// `app/page.js` is the UI for the `/` URL
export default function Page() {
  return <h1>Hello, Home page!</h1>
}
/* app/dashboard/page.js */

// `app/dashboard/page.js` is the UI for the `/dashboard` URL
export default function Page() {
  return <h1>Hello, Dashboard Page!</h1>
}

참고

  • 페이지는 항상 라우트 서브트리의 리프입니다.
  • .js, .ts, .tsx 확장자는 페이지 파일로 사용가능합니다.
  • 경로 세그먼트를 공개적으로 액세스하려면 page.js 파일이 필요합니다.
  • 페이지는 기본적으로 서버 컴포넌트이지만 클라이언트 컴포넌트로 설정할 수 있습니다.
  • 페이지는 데이터를 fetch 할 수 있습니다.

레이아웃

레이아웃은 여러 페이지 간에 공유되는 UI입니다. 웹 페이지를 탐색 시 레이아웃은 state를 유지하고 대화형을 유지하며 리렌더링되지 않습니다. 레이아웃도 중첩될 수 있습니다.

layout.js 파일에서 React 컴포넌트를 default로 export하여 레이아웃을 정의할 수 있습니다. 해당 컴포넌트는 렌더링 중에 자식 레이아웃(있는 경우) 또는 자식 페이지로 채워질 children prop을 가지고 있어야합니다.

/* app/dashboard/layout.js */

export default function DashboardLayout({
  children, // will be a page or nested layout
}) {
  return (
    <section>
      {/* Include shared UI here e.g. a header or sidebar */}
      <nav></nav>
 
      {children}
    </section>
  )
}

참고

  • 최상위 레이아웃을 Root Layout이라고 합니다. 루트 레이아웃은 반드시 존재해야하며, 항상 htmlbody태그를 포함합니다. 루트 레이아웃은 애플리케이션의 모든 페이지에서 공유됩니다.
  • 모든 경로 세그먼트에서는 선택적으로 자체 레이아웃을 정의할 수 있습니다. 이러한 레이아웃은 해당 세그먼트의 모든 페이지에서 공유됩니다.
  • 경로의 레이아웃은 기본적으로 중첩됩니다. 각 부모 레이아웃은 children prop을 사용하여 그 아래에 있는 자식 레이아웃을 래핑합니다.
  • 라우트 그룹을 사용하여 공유 레이아웃을 선택적으로 적용할 수 있습니다.
  • 레이아웃은 기본적으로 서버 컴포넌트이지만 클라이언트 컴포넌트로 설정할 수 있습니다.
  • 레이아웃은 데이터 fetch를 할 수 있습니다.
  • 부모 레이아웃과 그 자식 간에는 데이터를 전달할 수 없습니다. 그러나 경로에서 동일한 데이터를 두 번 이상 가져올 수 있으며 React는 성능에 영향을 주지 않고 요청을 자동으로 중복 제거합니다.
  • 레이아웃은 현재 라우트 세그먼트에 액세스할 수 없습니다. 라우트 세그먼트에 액세스하려면 클라이언트 컴포넌트에서 useSelectedLayoutSegment 또는 useSelectedLayoutSegments를 사용해야합니다.
  • .js, .ts, .tsx 확장자는 레이아웃 파일로 사용가능합니다.
  • layout.jspage.js 파일은 동일한 폴더에 정의할 수 있습니다. 레이아웃은 페이지를 래핑합니다.

루트 레이아웃(필수)

루트 레이아웃은 app 디렉토리의 최상위에 정의되며 모든 경로에 적용됩니다. 이 레이아웃을 사용하면 서버에서 반환된 초기 HTML을 수정할 수 있습니다.

/* app/layout.js */

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

참고

  • app 디렉토리는 반드시 루트 레이아웃을 포함해야합니다.
  • 루트 레이아웃에는 htmlbody 태그가 반드시 포함되어야합니다. Next.js는 이를 자동으로 생성해주지 않습니다.
  • 내장 SEO 지원을 사용해 <head> HTML 요소를 관리할 수 있습니다. ex) <title>
  • 라우트 그룹을 사용하여 복수의 루트 레이아웃을 생성할 수 있습니다.
  • 루트 레이아웃은 기본적으로 서버 컴포넌트이며 클라이언트 레이아웃으로 설정할 수 없습니다.

중첩 레이아웃

폴더 안에 정의된 레이아웃(예: app/dashboard/layout.js)은 특정 라우트 세그먼트(예: acme.com/dashboard)에 적용되며 해당 세그먼트가 활성화될 때 렌더링됩니다. 기본적으로 파일 계층 구조의 레이아웃은 중첩됩니다. 즉, children prop을 통해 자식 레이아웃을 래핑합니다.

/* app/dashboard/layout.js */

export default function DashboardLayout({ children }) {
  return <section>{children}</section>
}

참고

  • <html>, <body>태그는 루트 레이아웃에만 사용할 수 있습니다.

위의 두 레이아웃을 결합하는 경우 루트 레이아웃(app/layout.js)은 대시보드 레이아웃(app/dashboard/layout.js)을 래핑하고, 대시보드 레이아웃은 app/dashboard/* 내부의 라우트 세그먼트를 래핑합니다.

두 레이아웃은 다음과 같이 중첩됩니다.

또한, 라우트 그룹을 사용하여 공유 레이아웃을 선택적으로 적용할 수 있습니다.

템플릿(Templates)

템플릿은 하위 레이아웃 또는 페이지를 래핑한다는 점에서 레이아웃과 유사합니다. 경로 사이에서 지속되고 state를 유지하는 레이아웃과 달리 템플릿은 탐색 시 각 자식에 대해 새 인스턴스를 만듭니다. 즉, 사용자가 템플릿을 공유하는 라우트 사이를 탐색할 때 컴포넌트의 새 인스턴스가 마운트되고 DOM 요소가 다시 생성되며 state가 유지되지 않고 effect가 다시 동기화됩니다.

이러한 특정 동작이 필요한 경우가 있을 수 있으며, 다음같은 경우에 레이아웃보다 템플릿이 더 적합할 수 있습니다.

  • CSS 또는 애니메이션 라이브러리를 사용한 시작/종료 애니메이션 사용
  • useEffectuseState에 의존하는 기능 사용
  • 기본 프레임워크 동작을 변경하기 위해.
    예를 들어 레이아웃 내부의 Suspense 경계는 페이지를 전환할 때가 아니라 레이아웃이 처음 로드될 때만 대체 페이지(fallback)를 표시합니다. 템플릿의 경우 각 탐색에 대체 페이지가 표시됩니다.

템플릿을 사용할 특별한 이유가 없으면 레이아웃을 사용하는 것을 권장합니다.

템플릿은 template.js 파일에서 default로 React 컴포넌트를 export 해서 정의할 수 있습니다. 컴포넌트는 중첩된 세그먼트가 될 children prop을 가지고 있어야 합니다.

/* app/template.js */

export default function Template({ children }) {
  return <div>{children}</div>
}

레이아웃과 템플릿이 있는 라우트 세그먼트의 렌더링 결과는 다음과 같습니다.

<Layout>
  {/* Note that the template is given a unique key. */}
  <Template key={routeParam}>{children}</Template>
</Layout>

<head> 수정하기

app 디렉토리에서 내장 SEO 지원을 사용하여 title이나 meta같은 <head> HTML 요소를 수정할 수 있습니다.

메타데이터는 layout.js 또는 page.js 파일에서 metadata 객체 또는 generateMetadata 함수를 export 해서 정의할 수 있습니다.

/* app/page.js */

export const metadata = {
  title: 'Next.js',
}
 
export default function Page() {
  return '...'
}

참고 : 루트 레이아웃에 <title>이나 <meta>같은 태그를 <head> 태그에 직접 추가하면 안됩니다. <head> 요소 스트리밍이나 중복 제거와 같은 기능을 자동으로 관리하는 Metadata API를 사용해야합니다.


원문 - https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts

post-custom-banner

0개의 댓글