Next.js Parallel Routes(병렬 라우팅) 사용법

반응형

Next.js 13 이후 버전부터 app 디렉터리 방식으로 라우팅을 구현할 수 있습니다.

그중에 병렬 라우팅(Parallel Routes)에 대해서 알아보도록 하겠습니다.

 

병렬 라우팅이란? 

하나의 레이아웃에 여러 페이지를 동시에 또는 조건부로 렌더링 할 수 있습니다.

주로 대시보드나 피드에서 여러 가지 레이아웃이 역동적인 페이지에서 사용할 수 있습니다.

 

모달창과 같이 하나의 레이아웃에 여러 페이지를 띄울 수도 있습니다.

또 인증 정보 등 조건에 따라서 렌더링을 할 수 있습니다.

 

병렬 라우팅을 사용하면 레이아웃마다 각각 오류 처리와 로딩 상태를 정의할 수 있는 장점이 있습니다.

 

사용법

  1. slot name 을 이용해서 생성합니다. @folder 네이밍 컨벤션을 이용해서 slot를 생성합니다.
  2. layout.tsx에 props에서 렌더링 합니다.

app/@userInfo/page.tsx

import React from 'react';

const Page = () => {
    return (
        <div>
          User Info
        </div>
    );
};

export default Page;

 

app/layout.tsx

import React from "react";

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

 

예시

모달창 만들기

Link 를 이용하여 생성한 모달창을 오픈할 수 있습니다.

 

app/@modal/login

'use client'
import { useRouter } from 'next/navigation'

export default function Page() {
    const router = useRouter()
    return (
        <div>
            <h1>Login</h1>
            <span onClick={() => router.back()}>Close modal</span>
        </div>
    )
}

 

app/layout.tsx

import React from "react";

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

 

app/page.tsx

"use client";

import {Button} from "@/components/ui/button";
import Link from "next/link";

const Page =  () => {

    return (
            <Link href="/login">open modal</Link>
    );
};

export default Page;

 

조건부 렌더링 하기

아래와 같이 조건에 따라서 병렬 라우팅을 할 수 있습니다.

import React from "react";

export default function Layout(props: {
    children: React.ReactNode
    userInfo: React.ReactNode
    weather: React.ReactNode
}) {
    const bool = false;

    return (
        <>
            {props.children}
            {bool ? props.userInfo : props.weather}
        </>
    )
}
728x90
반응형