SPACE RUMI

Hi, I am rumi. Let's Splattack!

[STUDY] 스터디/NEXT.js Docs

[Routing] NEXT.js beta 한글 번역 : Routing - Pages and Layouts / 페이지와 레이아웃

백루미 2023. 4. 22. 01:44
반응형

Routing - Pages and Layouts : 페이지와 레이아웃

Next.js 13의 App Router에는 페이지, 공유 레이아웃 및 템플릿을 쉽게 만들 수 있는 새로운 파일 규칙이 도입되었습니다. 이 페이지에서는 Next.js 애플리케이션에서 이러한 특수 파일을 사용하는 방법을 안내합니다.

 

페이지

페이지는 route에 고유한 UI입니다. page.js 파일에서 컴포넌트를 내보내 페이지를 정의할 수 있습니다. 중첩 폴더를 사용하여 route를 정의하고 page.js 파일을 사용하여 route에 공개적으로 액세스할 수 있도록 합니다.

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

// `app/page.js`는 루트 `/` URL의 UI입니다.
export default function Page() {
  return <h1>Hello, Next.js!</h1>;
}

알아두면 좋습니다:

  • 페이지는 항상 경로 하위 트리의 리프입니다.
  • 페이지에는 .js, .jsx 또는 .tsx 파일 확장자를 사용할 수 있습니다.
  • route 세그먼트에 공개적으로 액세스하려면 page.js 파일이 필요합니다.
  • 페이지는 기본적으로 서버 컴포넌트이지만 클라이언트 컴포넌트로 설정할 수 있습니다.
  • 페이지는 데이터를 가져올 수 있습니다. 자세한 내용은 데이터 가져오기 섹션을 참조하세요.

 

레이아웃

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

레이아웃은 기본적으로 layout.js 파일에서 React 컴포넌트를 내보내서 정의할 수 있습니다. 컴포넌트는 렌더링 중에 자식 레이아웃(있는 경우) 또는 자식 페이지로 채워질 children prop를 받아들여야 합니다.

export default function DashboardLayout({
  children, // 페이지 또는 중첩 레이아웃이 됩니다.
}: {
  children: React.ReactNode,
}) {
  return (
    <section>
      {/* Include shared UI here e.g. a header or sidebar */}
      <nav></nav>

      {children}
    </section>
  );
}

알아두면 좋습니다:

  • 가장 위에 있는 레이아웃을 루트 레이아웃이라고 합니다. 이 필수 레이아웃은 애플리케이션의 모든 페이지에서 공유됩니다. 루트 레이아웃에는 htmlbody 태그가 포함되어야 합니다.
  • 모든 경로 세그먼트는 선택적으로 자체 레이아웃을 정의할 수 있습니다. 이러한 레이아웃은 해당 세그먼트의 모든 페이지에서 공유됩니다.
  • 경로의 레이아웃은 기본적으로 중첩됩니다. 각 부모 레이아웃은 React 자식 프로퍼티를 사용하여 그 아래의 자식 레이아웃을 감싸줍니다.
  • 라우트 그룹을 사용하여 공유 레이아웃 안팎에서 특정 라우트 세그먼트를 선택할 수 있습니다.
  • 레이아웃은 기본적으로 서버 컴포넌트이지만 클라이언트 컴포넌트로 설정할 수 있습니다.
  • 레이아웃은 데이터를 불러올 수 있습니다. 자세한 내용은 데이터 가져오기 섹션을 참조하세요.
  • 상위 레이아웃과 하위 레이아웃 간에 데이터를 전달할 수 없습니다. 그러나 route에서 동일한 데이터를 두 번 이상 가져올 수 있으며, React는 성능에 영향을 주지 않고 요청을 자동으로 중복 제거합니다.
  • 레이아웃에는 .js, .jsx 또는 .tsx 파일 확장자를 사용할 수 있습니다.
  • layout.js와 page.js 파일은 같은 폴더에 정의할 수 있습니다. 레이아웃이 페이지를 래핑합니다.

 

루트 레이아웃(필수)

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

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

알아두면 좋습니다:

  • app 디렉토리에 루트 레이아웃이 포함되어야 합니다.
  • Next.js가 자동으로 생성하지 않으므로 루트 레이아웃에 <html><body> 태그를 정의해야 합니다.
  • 기본 제공 SEO 지원을 사용하여 <head> HTML 요소(예: <title> 요소)를 관리할 수 있습니다.
  • route group을 사용하여 여러 루트 레이아웃을 만들 수 있습니다. 여기에서 예시를 참조하세요.
  • 루트 레이아웃은 기본적으로 서버 컴포넌트이며 클라이언트 컴포넌트로 설정할 수 없습니다.

페이지 디렉토리에서 마이그레이션: 루트 레이아웃이 _app.js 및 _document.js 파일을 대체합니다. 마이그레이션 가이드를 참조하세요.

 

레이아웃 중첩

폴더(예: app/dashboard/layout.js) 내에 정의된 레이아웃은 특정 route 세그먼트(예: 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 세그먼트를 감싸는 레이아웃을 감싸게 됩니다.

두 레이아웃은 이렇게 중첩됩니다:

경로 그룹을 사용하여 공유 레이아웃 안팎에서 특정 경로 세그먼트를 선택할 수 있습니다.

 

템플릿

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

이러한 특정 동작이 필요한 경우 레이아웃보다 템플릿이 더 적합한 옵션이 될 수 있습니다. 예를 들어

  • CSS 또는 애니메이션 라이브러리를 사용하여 애니메이션을 시작/종료하는 경우.
  • useEffect(예: 페이지 조회 수 로깅) 및 useState(예: 페이지별 피드백 양식)에 의존하는 기능.
  • 기본 프레임워크 동작을 변경합니다. 예를 들어 레이아웃 내부의 서스펜스 경계는 레이아웃을 처음 로드할 때만 폴백을 표시하고 페이지를 전환할 때는 표시하지 않습니다. 템플릿의 경우 각 탐색에 폴백이 표시됩니다. (이게 무슨말인지 이해가 잘 안되는데..)

권장 사항: 템플릿을 사용해야 할 특별한 이유가 없는 한 레이아웃을 사용하는 것이 좋습니다.

템플릿은 template.js 파일에서 기본 React 컴포넌트를 내보내서 정의할 수 있습니다. 컴포넌트는 중첩된 세그먼트가 될 children prop을 받아들여야 합니다.

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

레이아웃과 템플릿이 있는 route 세그먼트의 렌더링된 출력은 이와 같습니다:

<Layout>
 {/* 템플릿에는 고유 키가 주어집니다. */}
  <Template key={routeParam}>{children}</Template>
</Layout>

 

<head> 수정하기

app 디렉토리에서 기본 제공 SEO 지원을 사용하여 titlemeta 등의 <head> HTML 요소를 수정할 수 있습니다.
메타데이터는 metadata 객체를 내보내거나 layout.js 또는 page.js 파일에서 generateMetadata 함수를 사용하여 정의할 수 있습니다.

// app/page.tsx
export const metadata = {
  title: 'Next.js'
};

export default function Page() {
  return '...'
}

알아두면 좋습니다: 루트 레이아웃에 <title> 및 <meta>와 같은 <head> 태그를 수동으로 추가해서는 안 됩니다. 대신 <head> 요소의 스트리밍 및 중복 제거와 같은 고급 요구 사항을 자동으로 처리하는 메타데이터 API를 사용해야 합니다.

API 참조에서 사용 가능한 메타데이터 옵션에 대해 자세히 알아보세요.

반응형