하위 태스크 1
병렬 라우트 구조 생성
@folder 패턴으로 슬롯 디렉토리 생성
mkdir parallel
mkdir parallel/@sidebar
mkdir paraller/@feed하위 태스크 2
레이아웃에서 슬롯 사용
layout.tsx에서 슬롯 props 받기
app/parallel/layout.tsx:
import { ReactNode } from "react";
export default function ParallelLayout({ children, sidebar, feed } : {
children: ReactNode;
sidebar: ReactNode;
feed: ReactNode;
}) {
return (
<div>
<aside>{sidebar}</aside>
<main>{feed}</main>
{children}
</div>
);
}하위 태스크 3
default.tsx 구현
슬롯이 없을 때 기본 컴포넌트 표시
app/parallel/@feed/default.tsx:
export default function DefaultFeed() {
return <div>기본 피드</div>;
}app/parallel/@sidebar/default.tsx:
export default function DefaultSidebar() {
return <div>사이드 바</div>;
}app/parallel/layout.tsx:
import { ReactNode } from "react";
import DefaultSidebar from "./@sidebar/default";
import DefaultFeed from "./@feed/default";
export default function ParallelLayout({ children, sidebar, feed } : {
children: ReactNode;
sidebar: ReactNode;
feed: ReactNode;
}) {
return (
<div className="flex mx-auto w-200">
<aside className="w-50 bg-slate-200">{sidebar ?? <DefaultSidebar />}</aside>
<main className="w-100 bg-slate-100">{feed ?? <DefaultFeed />}</main>
<div className="w-50 bg-slate-300">{children}</div>
</div>
);
}app/parallel/page.tsx:
export default function Parallel() {
return <div>Parallel</div>;
}
하위 태스크 4
조건부 렌더링
URL에 따라 다른 슬롯 표시
app/parallel/one/page.tsx:
export default function ParallelOne() {
return <p>Parallel1</p>;
}app/parallel/@feed/one/page.tsx:
export default function Sidebar() {
return (
<p>첫 번째 평행 세계로 어서오세요!</p>
);
}
하위 태스크 5 ~ 6
가로채기 라우트 생성
(.) 패턴으로 라우트 가로채기
모달 컴포넌트 구현
모달 UI 컴포넌트 생성
app/@modal/(.)book/[id]/page.tsx:
import BookPage from "@/app/book/[id]/page";
import { ReactNode } from "react";
function Modal({ children }: { children: ReactNode }) {
return (
<div className="fixed flex h-screen w-screen items-center justify-center bg-slate-500 bg-opacity-50">
<div className="p-4 w-80 mx-auto bg-slate-200">{children}</div>
</div>
);
}
export default function InterceptedPage() {
return (
<Modal>
<BookPage />
</Modal>
);
}app/@modal/default.tsx:
export default function DefaultModal() {
return null;
}app/book/[id]/page.tsx:
export default function BookPage() {
return (
<article>
<ul className="pl-4 list-disc">
<h2 className="font-bold">별</h2>
<li>작가: 알퐁스 도데</li>
<li>출판: 더클래식</li>
<li>가격: 8,800원</li>
</ul>
</article>
);
}하위 태스크 7
모달 슬롯 추가
루트 레이아웃에 모달 슬롯 추가
app/layout.tsx:
import "./globals.css";
export default function RootLayout({
children,
modal,
}: Readonly<{
children: React.ReactNode;
modal: React.ReactNode;
}>) {
return (
<html lang="en">
<body className="min-h-full flex flex-col">
{children}
{modal}
</body>
</html>
);
}
하위 태스크 8
병렬 로딩 구현
각 슬롯의 독립적인 로딩 상태
app/parallel/@sidebar/loading.tsx:
export default function SidebarLoading() {
return <div>사이드 바 로딩...</div>;
}app/parallel/@feed/loading.tsx:
export default function FeedLoading() {
return <div>피드 로딩...</div>;
}하위 태스크 9
Route Groups 활용
괄호로 그룹화하여 레이아웃 공유
@modal, book, parallel, layout.tsx, page.tsx를 Route Group을 활용해 레이아웃을 공유시킬 수 있다.
mv @modal (example)/@modal
mv book (example)/book
mv parallel (example)/parallel
mv layout.tsx (example)/layout.tsx
mv page.tsx (example)/page.tsx