[next 13] Pages and Layouts

dana·2023년 6월 10일
4

Next.js

목록 보기
9/13
post-thumbnail

Pages

하나의 라우트에 해당하는 UI를 가진 파일

특징

  • Page는 항상 라우트 트리의 끝단
  • Pages의 파일 형식은 항상 .js , .jsx , .tsx
  • Page.js 파일은 공개적으로 접근 가능한 라우트를 만드는데 필요함
  • 기본적으로는 서버 컴포넌트이나, 클라이언트 컴포넌트도 가능
  • 데이터 fetching 가능

Layouts

여러 페이지간 공유되는 UI를 가진 파일

네비게이션 상에서 layouts은

  • 상태를 보존
  • 상호작용을 유지하고
  • 리렌더링하지 않음
  • 하위폴더에서도 사용 가능

만약 layout.js 파일에서 layout을 default로 export한 경우,
컴포넌트는 반드시 children prop을 받아야 함.
→ 렌더링되는 동안 보여질 예정

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>
  )
}

특징

  • 가장 최상위 layout (Root layout)은 전역에 적용되며, htmlbody 를 포함해야함. (필수 컴포넌트)
  • 최상위 레이아웃을 제외한 서브 레이아웃들은 optional. 한번 생성되면 위치한 폴더의 하위 페이지까지 적용됨
  • Layout은 기본적으로 중첩되어 사용됨
  • route 그룹을 사용해 공유 레이아웃 안밖에서 특정 route segment를 선택 할 수 있음.
  • Layout도 기본적으로 서버 컴포넌트
  • 데이터 fetching 가능
  • 상위 레이아웃에서 하위 레이아웃으로 데이터 전달 불가능. 하지만 같은 데이터를 여러번 받아와도 리액트에서 중복되는 호출을 알아서 제거해주기 때문에 성능에 영향을 미치지 않음
  • layout을 통해 현재 위치한 route segment에 접근 불가. 접근하기 위해선 client 컴포넌트의 useSelectedLayoutSegmentuseSelectedLayoutSegments 사용
  • layout 파일과 page 파일은 같은 폴더내에 위치 가능하며, 해당 Page를 layout이 감쌈

Root layout (필수)

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

특징

  • app 디렉토리는 반드시 하나의 root layout을 가지고 있어야 함.
  • next.js가 자동적으로 htmlbody 를 생성해주지 않기 때문에, 반드시 root layout에 포함되어야 함
  • 해당 html에 내장 SEO support 사용 가능
  • route group을 이용해 여러 root layout 생성 가능
    - app 폴더에 바로 layout을 만들지 않더라도, app 폴더의 하위 폴더들에 htmlbody를 포함한 폴더만의 root layout을 만들어 적용 가능
  • pages directory → app directory로 마이그레이션시, 기존 _app.js_document.jslayout 로 변경

Nested layout

상위 레이아웃은 하위 레이아웃 및 파일들을 children props 를 통해 감싸게 됨.

Templates

하위 layout이나 page를 감싼다는 점에서 layout과 비슷
경로 전체에서 상태를 유지하는 layout과 달리 template은 각 하위 항목에 대해 새 인스턴스 생성
→ template을 공유하는 페이지간 이동시, 상태는 reset되고 effect는 재실행됨

사용 예시

  • 입장/퇴장 애니메이션이 있는 라이브러리
  • useEffect이나 useState 기반의 기능
  • 프레임워크의 기본 동작을 바꾸는 경우, (ex, suspense는 처음 로드시에만 fallback을 보여주는데, 페이지 이동시마다 fallback을 보여줘야 하는 경우)

→ 위 상황이 아니라면 layout 사용이 권장됨.

export를 default로 하는 경우, 중첩된 segment 전역에 적용
→ 그게 아니라면 self로 호출해야하나?
- self로 호출시, unique key를 넘겨주어야 함.

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

Modifying <head>

metadata 객체나 generateMetadata를 export해 layout 이나 page 에서 사용함으로써 적용 가능

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

metadata를 <head>에 수동으로 입력할 필요 없이 Metadata api를 사용해 <head> 요소의 스트리밍 및 중복 제거와 같은 고급 요구사항을 자동으로 처리

profile
PRE-FE에서 PRO-FE로🚀🪐!

0개의 댓글