[Next.js] Parallel Routes

파이리·2023년 8월 2일
0

Next.js

목록 보기
10/18

병렬 라우팅을 사용하면 동일한 레이아웃에서 하나 이상의 페이지를 동시에 또는 조건부로 랜더링할 수 있습니다. 소셜 사이트의 대시보드 및 피드와 같이 앱에서 매우 동적인 섹션의 경우 병렬 라우팅을 사용하여 복잡한 라우팅 패턴을 구현할 수 있습니다.

예를 들어 Team 페이지와 Analytics 페이지를 함께 랜더링할 수 있습니다.

병렬 라우팅을 사용하면 각 경로가 독립적으로 스트리밍될 때 각 경로에 대해 독립적인 오류 및 로딩 상태를 정의할 수 있습니다.

병렬 라우팅을 사용하면 인증 상태와 같은 특정 조건에 따라 조건부로 슬롯을 랜더링할 수 있습니다. 이를 통해 동일한 URL에서 완전히 분리된 코드를 사용할 수 있습니다.

Convention

병렬 라우트는 명명된 슬롯을 사용하여 생성됩니다. 슬롯은 @폴더 규칙으로 정의되며 소품과 동일한 수준의 레이아웃으로 전달됩니다.

슬롯은 Route Segment가 아니며 URL 구조에 영향을 미치지 않습니다. 파일 경로는 /@team/members/members에서 엑세스할 수 있습니다.

예를 들어, 다음 파일 구조는 두 개의 명시적 슬롯을 정의합니다.

위의 폴더 구조는 이제 app/layout.js의 컴포넌트가 @analytics@team 슬롯 프로퍼티를 허용하고 하위 프로퍼티와 함께 병렬로 랜더링할 수 있다는 것을 의미합니다.

export default function Layout(props: {
  children: React.ReactNode
  analytics: React.ReactNode
  team: React.ReactNode
}) {
  return (
    <>
      {props.children}
      {props.team}
      {props.analytics}
    </>
  )
}

Unmatched Routes

기본적으로 슬롯 내에서 랜더링되는 콘텐츠는 현재 URL과 일치합니다.

Unmatched 라우트의 경우 라우팅 기술 및 폴더 구조에 따라 Next.js가 랜더링하는 콘텐츠가 달라집니다.

Next.js가 현재 URL을 기반으로 슬롯의 활성 상태를 복구할 수 없을 때 대체 파일로 default.js 파일을 정의할 수 있습니다.

다음 폴더 구조를 고려하세요. 팀 슬롯에는 setting 디렉터리가 있지만 @anayltics에는 setting디렉터리가 없습니다.

루트 / 에서 /settings까지 탐색하는 경우 탐색 유형과 default.js 파일의 사용 기능 여부에 따라 랜더링되는 콘텐츠가 달라집니다.

soft navigation에서는 현재 URL과 일치하지 않더라도 슬롯의 이전에 활성회된 상태를 랜더링합니다.

hard navgation에서는 Next.js는 먼저 URL과 일치하지 않는 슬롯의 default.js 파일을 랜더링하려고 시도합니다. 해당 파일을 사용할 수 없는 경우 404가 랜더링됩니다.

useSelectLayoutSegment(s)

useSelectedLayoutSegmentuseSelectedLayoutSegments 모두 해당 슬롯 내의 active segment을 읽을 수 있는 parallelRoutesKey를 허용합니다.

'use client'
 
import { useSelectedLayoutSegment } from 'next/navigation'
 
export default async function Layout(props: {
  //...
  authModal: React.ReactNode
}) {
  const loginSegments = useSelectedLayoutSegment('authModal')
  // ...
}

사용자가 URL 표시줄에서 @authModal/login 또는 /login으로 이동하면 로그인 세그먼트는 login 문자열과 동일합니다.

Examples

병렬 라우팅을 통해 모달을 랜더링할 수 있습니다.

@authModal 슬롯은 일치하는 경로로 이동하여 표시할 수 있는 <Modal> 컴포넌트를 랜더링합니다.

export default async function Layout(props: {
  // ...
  authModal: React.ReactNode
}) {
  return (
    <>
      {/* ... */}
      {props.authModal}
    </>
  )
}
import { Modal } from 'components/modal'
 
export default function Login() {
  return (
    <Modal>
      <h1>Login</h1>
      {/* ... */}
    </Modal>
  )
}

모달이 활성화되어 있지 않을 때 모달의 콘텐츠가 랜더링되지 않도록 하려면 null을 반환하는 dafualt.js 파일로 만들면 됩니다.

export default function Default() {
  return null
}

클라이언트 navigation을 통해 모달이 열렸을 경우 route.back()을 호출하거나 링크 컴포넌트를 사용하여 모달을 해제할 수 있습니다.

'use client'
import { useRouter } from 'next/navigation'
import { Modal } from 'components/modal'
 
export default async function Login() {
  const router = useRouter()
  return (
    <Modal>
      <span onClick={() => router.back()}>Close modal</span>
      <h1>Login</h1>
      ...
    </Modal>
  )
}

다른 곳으로 이동하여 모달을 해제하려는 경우 catch-all 라우트를 사용할 수 있습니다.

Conditional Routes

병렬 라우트를 사용하여 조건부 라우팅을 구현할 수 있습니다. 예를 들어 인증 상태에 따라 @dashboard또는 @login을 랜더링할 수 있습니다.

import { getUser } from '@/lib/auth'
 
export default function Layout({
  dashboard,
  login,
}: {
  dashboard: React.ReactNode
  login: React.ReactNode
}) {
  const isLoggedIn = getUser()
  return isLoggedIn ? dashboard : login
}

profile
프론트엔드 개발자

0개의 댓글