[ Routing ] Parallel Routes

차차·2023년 5월 17일
1

Next Docs

목록 보기
10/34
post-thumbnail

Parallel Routes

병렬 라우팅은 동시에 혹은 조건에 따라 동일한 레이아웃에서 하나 이상의 페이지를 렌더링하는 기능이다.

대시보드나 소셜 사이트의 피드와 같이 매우 동적인 앱 섹션에 대해, 병렬 라우팅을 사용하여 복잡한 라우팅 패턴을 구현할 수 있다.


예를 들어, 팀 페이지와 분석 페이지를 동시에 렌더링할 수 있다.

병렬 라우팅은 각 경로에 대해 독립적인 오류 및 로딩 상태를 정의할 수 있다. 이는 각 경로가 독립적으로 스트리밍되는 동안 사용된다.

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



규칙

병렬 경로는 이름이 지정된 슬롯을 사용하여 생성된다. 슬롯은 @폴더 형식으로 정의되며, 동일 레벨의 레이아웃으로 props로 전달된다.

슬롯은 라우트 세그먼트가 아니며 URL 구조에 영향을 주지 않는다. 파일 경로 /@team/members/members에서 접근할 수 있다.


예를 들어, 다음과 같은 파일 구조는 @analytics@team 두 개의 명시적인 슬롯을 정의한다.

위의 폴더 구조는 app/layout.js 컴포넌트가 @analytics@team 슬롯 props를 받아들이고, 자식 props와 함께 병렬로 렌더링할 수 있도록 한다.

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

💡  알아두면 좋은 점

children props는 폴더에 매핑될 필요가 없는 암묵적인 슬롯이다. 이는 app/page.jsapp/@children/page.js와 동등하다는 것을 의미한다.



일치하지 않는 경로

기본적으로, 슬롯 내에서 렌더링되는 내용은 현재 URL과 일치하다.

일치하지 않는 슬롯의 경우, Next.js가 렌더링하는 내용은 라우팅 기술과 폴더 구조에 따라 다르다.


default.js

default.js 파일을 정의하여 현재 URL을 기반으로 슬롯의 활성 상태를 복구할 수 없을 때 Next.js가 대체로 렌더링되도록 할 수 있다.


아래와 같은 폴더를 살펴보자. @team 슬롯은 settings 디렉토리를 가지고 있지만, @analytics 슬롯은 그렇지 않다.

루트 /에서 /settings로 이동한다면, 렌더링되는 내용은 네비게이션의 유형과 default.js 파일의 유무에 따라 다를 수 있다.

With @analytics/default.jsWithout @analytics/default.js
Soft Navigation@team/settings/page.js and @analytics/page.js@team/settings/page.js and @analytics/page.js
Hard Navigation@team/settings/page.js and @analytics/default.js404

💡  Soft Navigation

소프트 네비게이션 시에는 Next.js가 슬롯의 이전에 활성화된 상태를 렌더링한다. 이는 현재 URL과 일치하지 않더라도 해당 상태를 보존한다.


💡  Hard Navigation

페이지 전체를 다시 로드하는 네비게이션인 하드 네비게이션의 경우, Next.js는 먼저 일치하지 않는 슬롯의 default.js 파일을 렌더링하려고 시도한다. 이 파일이 없는 경우 404가 렌더링됩니다.

일치하지 않는 경로에 대한 404는 병렬로 렌더링되지 않아야 할 경로를 실수로 렌더링하지 않도록 도와준다.



useSelectedLayoutSegment(s)

useSelectedLayoutSegmentuseSelectedLayoutSegmentsparallelRoutesKey를 받아들여 해당 슬롯 내에서 활성 경로 세그먼트를 읽을 수 있도록 한다.

// app/layout.tsx

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

사용자가 @authModal/login 또는 URL 주소창에서 /login으로 이동할 경우, loginSegments"login"이라는 문자열과 동일하다.



예시

Modal 렌더링

병렬 라우팅은 모달을 렌더링하는 데 사용할 수 있다.

@authModal 슬롯은 일치하는 경로로 이동하면 표시될 수 있는 <Modal> 컴포넌트를 렌더링한다. 예를 들어 /login과 같은 경로로 이동할 때 모달이 표시될 수 있다.

// app/layout.tsx

export default async function Layout(props: {
  // ...
  authModal: React.ReactNode;
}) {
  return (
    <>
      {/* ... */}
      {props.authModal}
    </>
  );
}
// app/@authModal/login/page.tsx

import { Modal } from 'components/modal';
 
export default function Login() {
  return (
    <Modal>
      <h1>Login</h1>
      {/* ... */}
    </Modal>
  );
}

모달이 비활성화되었을 때 모달의 내용이 렌더링되지 않도록 하려면, null을 반환하는 default.js 파일을 생성할 수 있다.

export default function Default() {
  return null;
}

Modal 닫기

클라이언트 네비게이션을 통해 모달이 시작된 경우, 예를 들어 <Link href="/login">을 사용하여 모달을 표시한 경우, router.back()을 호출하거나 Link 컴포넌트를 사용하여 모달을 닫을 수 있다.

'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 route를 사용할 수도 있다.

// app/@authModal/[...catchAll]/page.js

export default function CatchAll() {
  return null;
}

catch-all routedefault.js보다 우선순위를 가진다.



조건부 라우팅

조건부 라우팅을 구현하기 위해 병렬 라우트를 사용할 수 있다.

예를 들어, 인증 상태에 따라 @dashboard 또는 @login 경로를 렌더링할 수 있다.

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


[출처]
https://nextjs.org/docs/app/building-your-application/routing/parallel-routes

profile
나는야 프린이

0개의 댓글