[ Routing ] Pages and Layouts

차차·2023년 5월 15일
0

Next Docs

목록 보기
4/34
post-thumbnail
post-custom-banner

Next.js 13 내부의 App Router는 페이지, 공유 레이아웃템플릿을 쉽게 생성하기 위한 새로운 파일 규칙을 도입했다. 이 페이지에서는 Next.js 애플리케이션에서 이러한 특별한 파일을 사용하는 방법을 안내한다.



Pages

페이지는 경로에 고유한 UI이다. page.js 파일에서 컴포넌트를 내보내어 페이지를 정의할 수 있다.

중첩된 폴더를 사용하여 경로를 정의하고 페이지.js 파일을 사용하여 경로에 대해 공개적으로 액세스할 수 있도록 한다.


앱 디렉토리 내에 page.js 파일을 추가하여 첫 번째 페이지를 만들어 보자.

// app/page.tsx

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

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

참고사항

  • 페이지는 항상 라우트 서브트리의 말단이다.

  • .js, .jsx, 또는 .tsx 파일 확장명을 페이지에 사용할 수 있다.

  • 라우트 세그먼트를 공개적으로 액세스할 수 있도록 하려면 page.js 파일이 필요하다.

  • 페이지는 기본적으로 서버 컴포넌트이지만 클라이언트 컴포넌트로 설정할 수도 있다.

  • 페이지는 데이터를 가져올 수 있다.



Layouts

레이아웃은 여러 페이지 간에 공유되는 UI이다. 탐색 중에 레이아웃은 상태를 유지하고 상호작용하며 다시 렌더링되지 않는다. 레이아웃은 중첩될 수도 있다.

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

// 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이라고 하며, 이는 애플리케이션의 모든 페이지에서 공유된다. Root layout에는 html 및 body 태그가 포함되어야 한다.

  • 어떤 경로 세그먼트든지 자체 레이아웃을 선택적으로 정의할 수 있다. 이러한 레이아웃은 해당 세그먼트의 모든 페이지에서 공유된다.

  • 라우트의 레이아웃은 기본적으로 중첩된다. 각 부모 레이아웃은 React children prop을 사용하여 그 아래에 있는 자식 레이아웃을 감싼다.

  • 공유된 레이아웃을 선택적으로 사용하려면 Route Groups를 사용할 수 있다.

  • 레이아웃은 기본적으로 서버 컴포넌트이지만 클라이언트 컴포넌트로 설정할 수도 있다.

  • 레이아웃은 데이터를 가져올 수 있다. Data Fetching

  • 부모 레이아웃과 그 자식 간에 데이터를 전달할 수는 없다. 그러나 경로에서 동일한 데이터를 여러 번 가져올 수 있으며, React는 자동으로 요청을 제거하여 성능에 영향을 미치지 않는다.

  • 레이아웃은 현재 경로 세그먼트에 액세스할 수 없다. 경로 세그먼트에 액세스하려면 클라이언트 컴포넌트에서 useSelectedLayoutSegment 또는 useSelectedLayoutSegments를 사용할 수 있다.

  • .js.jsx, or .tsx 확장자를 사용할 수 있다.

  • 동일한 폴더에 layout.js 파일과 page.js 파일을 정의할 수 있다. 레이아웃은 페이지를 래핑한다.



Root Layout (Required)

루트 레이아웃은 app 디렉토리의 최상위 수준에서 정의되며 모든 경로에 적용된다.

이 레이아웃을 사용하면 서버에서 반환된 초기 HTML을 수정할 수 있다.

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

[ 참고 사항 ]

  • app 디렉토리는 Root layout을 포함해야 한다.

  • 루트 레이아웃은 <html><body> 태그를 정의해야 한다. Next.js에서 자동으로 생성하지 않기 때문이다.

  • 빌트인 SEO 지원을 사용하여 <head> HTML 요소를 관리할 수 있다. 예를 들어, <title> 요소를 사용할 수 있습니다.

  • root groups를 사용하여 여러 루트 레이아웃을 만들 수 있다.

  • 루트 레이아웃은 기본적으로 Server Component이며, Client Component로 설정할 수 없다.

  • pages 디렉토리에서 마이그레이션하는 경우, 루트 레이아웃은 _app.js_document.js 파일을 대체한다.



Nesting Layouts

폴더 내에서 정의된 레이아웃 (예: app/dashboard/layout.js)은 특정 경로 세그먼트 (예: acme.com/dashboard)에 적용되고 해당 세그먼트가 활성화되면 렌더링된다.

파일 계층 구조에서 레이아웃은 기본적으로 중첩되어 있으며, children prop을 통해 하위 레이아웃을 감싸게 된다.

// 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/* 내부의 경로 세그먼트를 감싸게 된다.


👇 두 레이아웃은 아래와 같이 중첩된다.

공유 레이아웃에 특정 경로 세그먼트를 선택적으로 포함하거나 제외하려면 Route Groups를 사용할 수 있다.



Templates

템플릿은 레이아웃과 유사하게 각 자식 레이아웃이나 페이지를 래핑한다.. 레이아웃은 라우트 간에 지속되고 상태를 유지하지만, 템플릿은 각각의 자식에 대해 새 인스턴스를 만든다. 따라서 라우트를 이동하는 경우, 템플릿을 공유하는 라우트 간에 이동하면 컴포넌트의 새 인스턴스가 마운트되고 DOM 요소가 다시 생성되며, 상태는 보존되지 않으며 효과가 다시 동기화된다.


아래와 같은 특정 동작이 필요한 경우 레이아웃 대신에 템플릿을 사용하는 것이 더 적합할 수 있다.

  • CSS나 애니메이션 라이브러리를 사용한 입/출 애니메이션
  • useEffect(예: 페이지 조회 기록 기록) 혹은 useState(예: 페이지별 피드백 폼)에 의존하는 기능
  • 기본 프레임워크 동작 변경. 예를 들어, 레이아웃 내의 Suspense 경계는 레이아웃이 처음로드될 때만 대체 내용을 표시하고 페이지를 전환할 때는 표시하지 않는다. 템플릿의 경우 대체 내용이 각 탐색마다 표시된다.

특별한 이유가 없다면 레이아웃을 사용하는 것이 좋다.


템플릿은 template.js파일에서 기본적으로 React 컴포넌트를 내보내어 정의할 수 있다. 이 컴포넌트는 중첩된 세그먼트인 children prop을 수락해야 한다.

// app/template.tsx

export default function Template({ children }: { children: React.ReactNode }) {
  return <div>{children}</div>;
}
// app/template.tsx

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>


Modifying <head>

app 디렉토리에서 내장된 SEO 지원을 사용하여 제목 및 메타 데이터와 같은 <head> HTML 요소를 수정할 수 있다.


메타 데이터layout.js 또는 page.js 파일에서 metadata 객체 또는 generateMetadata 함수를 exporting 하여 정의할 수 있다.

import { Metadata } from 'next';
 
export const metadata: Metadata = {
  title: 'Next.js',
};
 
export default function Page() {
  return '...';
}

루트 레이아웃에 <title><meta>와 같은 <head> 태그를 수동으로 추가해서는 안된다. 대신 Metadata API를 사용하여 스트리밍 및 <head> 요소 중복 제거와 같은 고급 요구 사항을 자동으로 처리해야 한다.


[ 출처 ]
https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts

profile
나는야 프린이
post-custom-banner

0개의 댓글