모달은 웹 서비스 제작 시 자주 활용되며, 사용자의 주의를 집중시키고 상호 작용을 유도하여 사용자 경험을 향상시킬 수 있습니다. 이러한 모달을 React
로 제작한다면 열림/닫힘 상태 관리, 모달안의 이벤트 핸들링 등 신경써야하는 부분이 존재합니다. Next.js
에서는 병렬 라우트과 인터셉션 라우트를 함께 사용하여 멋지게 모달을 관리할 수 있습니다.
병렬 라우트를 사용하면 동일한 레이아웃 내에서 하나 이상의 페이지를 동시에 또는 조건부로 렌더링할 수 있습니다. 하나의 페이지에서 대시보드 및 동적인 섹션이 필요한 경우 유용하게 사용할 수 있습니다.
병렬 라우트를 사용하기 위해서는 slots
을 사용해야 합니다. @folder
와 같이 정의한 slots
은 상위 레이아웃에서 props
으로 전달해야 하고 경로로 구분되지 않아 URL 구조에 영향을 주지 않습니다.
export default function Layout({
children,
team,
analytics,
}: {
children: React.ReactNode
analytics: React.ReactNode
team: React.ReactNode
}) {
return (
<>
{children}
{team}
{analytics}
</>
)
}
인터셉션 라우트는 현재 레이아웃에서 애플리케이션의 다른 부분의 경로를 로드할 수 있습니다. 이는 다른 컨텍스트로 전환하지 않고도 경로의 내용을 표시하려는 경우 유용할 수 있습니다.
인터셉션 라우트는 (..)
을 사용하여 정의할 수 있습니다.
(.)
: 동일한 레벨의 세그먼트(..)
: 한 레벨 위의 세그먼트(..)(..)
: 두 레벨 위의 세그먼트(...)
: 루트 레벨인 app
디렉터리의 세그먼트위와 같이 (..)photo
폴더는 photo
세그먼트를 인터셉트할 수 있습니다.
병렬 라우트과 인터셉션 라우트를 함께 사용하여 모달을 관리한다면 여러 이점이 존재합니다.
URL을 통한 모달의 콘텐츠 공유가 가능합니다.
모달을 닫는 대신 페이지를 새로 고칠 경우 컨텍스트를 유지합니다.
뒤로 페이지를 이동하여 모달을 닫을 수 있습니다.
앞으로 페이지를 이동하여 모달을 다시 열 수 있습니다.
모달을 제작하기 위해서는 기본 경로와 slots
을 인터셉션 라우트를 사용하여 동일한 레벨의 세그먼트로 일치시켜주어야 합니다.
default.tsx
파일은 Next.js
가 초기 로드 및 전체 페이지를 새로 고침 시 일치하지 않는 slots
에 대한 대체 랜더링 파일입니다.
export default function Default() {
return null
}
위와 같이 null
을 return 하면 모달이 활성화되지 않을 때 렌더링되지 않습니다.
export default function Layout({
children,
modal,
}: {
children: React.ReactNode
modal: React.ReactNode
}) {
return (
<div>
<Link href='/modal'>Open Modal</Link>
{children}
{modal}
</div>
)
}
이제 <Link>
를 클릭하면 페이지로 이동하는 대신 모달이 열립니다. 모달이 열린 상태에서 새로고침을 한다면 기본 경로로 이동하게 됩니다.
모달의 닫기 위해서는 router.back()
을 사용하거나 Link
를 이용하여 null
을 return하는 catch-all
라우트 사용하여 모달을 닫을 수 있습니다.
import Link from 'next/link'
export function Modal({ children }: { children: React.ReactNode }) {
return (
<>
<Link href="/">Close modal</Link>
<div>{children}</div>
</>
)
}
// app/@modal/[...catchAll]/page.tsx
export default function CatchAll() {
return null
}
또한 병렬 라우트는 독립적으로 스트리밍이 되므로 가 경로에 대해 로딩 및 에러 상태를 정의할 수 있습니다.
Next.js
의 병렬 라우트와 인터셉트 라우트를 사용하여 모달을 구성한다면 동적이고 사용자의 경험을 향상시킬 수 있는 서비스를 제작할 수 있을 것 같습니다. 다만 병렬 라우트와 인터셉트 라우트를 사용하여 만든 모달의 장점을 크게 이용할 수 없는 경우(간단한 알림창) 전에 사용하던 방법으로 모달을 구성하는 편이 더 좋아보입니다.