최근 Next.js 프로젝트를 진행하며 parallel 라우트를 사용한 모달 구현 방법을 적용해 보았다.
기존에 자주 사용했던 State + Portal 방식을 사용하는 모달과 비교하며 느낀 장점과 한계를 정리해보려고 한다.
Parallel 라우트는 Next.js에서 제공하는 기능 중 하나로, URL 경로에 영향을 주지 않으면서도 각 컴포넌트를 독립적으로 렌더링할 수 있게 해준다.
특히 로딩이나 에러 상태 관리, 데이터 캐싱 등을 Next.js에서 자동으로 최적화하여 제공한다.
기존의 모달 구현 방식은 React의 State와 React Portal을 이용하여 구현하는 방법이다.
구현이 직관적이고 간단함.
URL에 영향을 미치지 않기 때문에 모달의 상태만으로 간단히 관리할 수 있음.
상태 관리 코드가 증가하며 유지보수가 어려워질 수 있음.
웹뷰(Android) 환경에서 물리적인 백버튼을 눌렀을 때 추가적인 코드가 필요하여 복잡성 증가.
뒤로가기나 페이지 전환 시 모달 상태 관리가 까다로워질 수 있음.
// 기존 방식 모달 예시
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(true)}>모달 열기</button>
{open && ReactDOM.createPortal(
<div className="modal">
모달 내용
<button onClick={() => setOpen(false)}>닫기</button>
</div>,
document.getElementById('modal-root')
)}
</>
);
별도의 상태 관리 코드가 필요 없으므로 코드가 간결해지고 유지보수가 쉬워진다.
브라우저의 뒤로가기 버튼을 이용하여 모달을 자연스럽게 닫을 수 있어 UX 상승
Next.js에서 fetch 요청을 자동으로 최적화 관리
기본적으로 소프트 내비게이션(CSR, router.push 또는 Link 사용)에 적합하며, 하드 내비게이션(새로고침, 직접적인 URL 접근) 처리에는 한계가 있다.
중첩된 모달을 구현시, 추가적인 parallel route 슬롯을 만들어야 하는 복잡성이 있다.
// 폴더 구조
app/
├── @modal
│ └── modal
│ └── page.jsx
└── page.jsx
// Parallel 라우트를 이용한 모달 예시
// page.jsx
import Link from 'next/link';
export default function Page() {
return (
<>
<Link href="/@modal/modal" scroll={false}>모달 열기</Link>
</>
);
}
// @modal/modal/page.jsx
export default function Modal() {
return (
<div className="modal">
모달 내용
</div>
);
}
Parallel 라우트를 이용한 모달 구현은 다음과 같은 경우에 유리하다.
반면, 다음과 같은 상황에서는 기존의 State + Portal 방식이 더 적합하다.
프로젝트의 특성과 요구 사항에 따라 적절한 방식을 선택하면 최적의 개발 경험과 사용자 경험을 제공할 수 있을 것이다.