자주써도 헷갈리는 parallel routes 와 intercepting routes 로
기본적인 modal 만드는 법을 정리해보려고 합니다.
1. Parallel Routes
Parallel Routes 는 모달을 만들기 위한 기능은 아닙니다.
공식문서에 따르면,
Parallel Routes를 사용하면 동일한 레이아웃 내에서 하나 이상의 페이지를 동시에
또는 조건부로 렌더링할 수 있습니다. 대시보드나 피드와 같이 앱의 매우 동적인 섹션에 유용합니다. 예를 들어 대시보드에서 Parallel Routes를 사용하여팀 페이지와 분석 페이지를 동시에 렌더링할 수 있습니다
라고 합니다.
만드는 법은 아래처럼 @ 를 붙여서(슬롯이라고 합니다) 폴더를 생성하고 page.tsx 만들면 됩니다.
app/
├─ @modal/
│ ├─ example/
│ │ └─ page.tsx
│ └─ default.tsx
├─ example/
│ └─ page.tsx
├─ layout.tsx
└─ page.tsx
그리고 layout.tsx 에 아래처럼 설정합니다.
interface LayoutProps {
children: React.ReactNode;
modal: React.ReactNode;
};
function Layout({ children, modal }: LayoutProps) {
return (
<>
{children}
{modal}
</>
)
};
export default Layout;
주의점은 슬롯은 경로 세그먼트가 아니며 URL 구조에 영향을 미치지 않습니다.
예를 들어 /@modal/example 의 경우 @modal 이 슬롯이므로 URL은 /example 가 됩니다.
(슬롯은 url 에 영향을 주지 않고 무시됩니다)
이 예시에서는, /example 로 접속시 children 부분에는 /example
이,
modal 부분에는 /@modal/example
이 매핑됩니다.
만약 / 로 접속한다면 children 부분에는 app/page.tsx 가 맵핑되고
{modal} 부분에는 default.tsx 가 맵핑될 것입니다.
default.tsx 는 Parallel Routes가 이용되지 않을 때(경로가 unmatched 일 때)
이 페이지를 디폴트로 보여줍니다.
(하드네비게이션, 소프트네비게이션 차이가 있는데 공식문서 를 참조하면 좋습니다)
여기까지 아주 기본적인 Parallel Routes 의 개념입니다.
그러나 이 상태로는 /example 로 소프트 네비게이션시 병렬적으로(동시에)/example
과 /@modal/example
이 렌더링 되므로 모달과는 다릅니다.
여기서부터 Intercepting Routes 를 알아보아야 합니다.
2. Intercepting Routes
Intercepting Routes 는 이름처럼 라우트를 '가로챕'니다.
공식문서에서는 다음처럼 설명하고 있습니다.
Intercepting Routes는 현재 레이아웃 내에서 애플리케이션의 다른 부분의 경로를 로드할 수 있습니다.
이 라우팅 패러다임은 사용자가 다른 컨텍스트로 전환하지 않고도 경로의 콘텐츠를 표시하려는 경우에
유용할 수 있습니다.
즉, 현재 페이지 컨텍스트를 유지한 채로 새로운 라우트를 렌더링 해줍니다.
따라서 주소를 바꾸지않고 다른 주소의 페이지들을 렌더링 할 수 있습니다.
Intercepting Routes 는 (..)
와 같은 컨벤션으로 정의됩니다.
(.)
동일한 라우팅 레벨 세그먼트에 매칭(..)
부모 라우팅 레벨 세그먼트에 매칭(..)(..)
2단계 윗 레벨(…)
app 디렉토리 루트 요소에 매칭
이때 기준은 경로 세그먼트(브라우저 주소...) 이므로 폴더구조와 혼동되면 안됩니다.
따라서 아래처럼 될 수 있습니다.
app/
├─ @modal/
│ ├─ (.)example/
│ │ └─ page.tsx
│ └─ default.tsx
├─ example/
│ └─ page.tsx
├─ layout.tsx
└─ page.tsx
폴더 구조상으로는 app/@modal/(.)example 로 app/example 과 다른 레벨에 있는 것 같지만
경로 세그먼트 기준이므로, @modal은 무시되어 둘은 같은 레벨임에 주의하면 됩니다.
이렇게 모달을 만들시 좋은 점은 공식문서에 따르면 다음과 같습니다.
- 뒤로가기(router.back())로 모달을 열고 닫을 수 있음
- URL 공유를 통해 모달 내용 공유 가능
- 페이지 새로고침 시 모달 안닫힘
즉, 경로로 접근시 모달이 뜨기 때문에 모달 자체를 url 로 관리할 수 있습니다.
많이 쓰는 방법인 createPortal 에 비해 분명한 장점이 있습니다.
그러나 방법이 어떻게 보면 더 난해(?) 할 수도 있기 때문에
필요에 따라 쓰면 좋을 것 같습니다.
추가로, Parallel, Intercepting routes 의 사용법은 모달을 만들기 위한 것은 아닙니다.
그냥 모달로 쓰면 좋고 공식문서에도 예제로 나올 뿐이라고 생각됩니다.
이외에도 사용법이 많으니 공식문서를 한번 정리해봐야겠습니다...
+ 각 파일의 내용
// app/@modal/default.tsx
export default function Default() {
return null
}
// app/@modal/(.)example/page.tsx
import { Sample, Modal } from "@/components";
function InterceptingPage() {
return (
<Modal>
<Sample />
</Modal>
);
}
export default InterceptingLoginPage;
// app/example/page.tsx
import { Sample } from "@/components";
function Page() {
return (
<Sample />
);
}
export default Page;
// app/layout.tsx
interface LayoutProps {
children: React.ReactNode;
modal: React.ReactNode;
};
function Layout({ children, modal }: LayoutProps) {
return (
<>
{children}
{modal}
</>
);
}
export default Layout;
'TIL' 카테고리의 다른 글
[241016 TIL] stateful/less, OOP vs FP.. 등(GPT 질의) (4) | 2024.10.16 |
---|---|
[241011 TIL] 싱글톤(Singleton) 패턴(gpt 질의) (1) | 2024.10.10 |
[241007 TIL] git credential 이상할때 (1) | 2024.10.06 |
[241006 TIL] supabase Redirect URLs (0) | 2024.10.06 |
[241005 TIL] 컴포넌트를 커스텀 훅으로 제공하기 (0) | 2024.10.05 |