React Portal을 활용한 모달 컴포넌트 구현
문제 상황
관리자 페이지에서 중첩된 레이아웃 안에 모달을 띄우는 작업을 하다가 z-index 문제가 발생했다. 부모 요소의 overflow: hidden과 position: relative 속성 때문에 모달이 제대로 표시되지 않았다.
React Portal 적용
ReactDOM.createPortal을 사용하면 컴포넌트를 DOM 트리의 다른 위치에 렌더링할 수 있다.
import { createPortal } from 'react-dom';
import { useEffect, useState } from 'react';
const Modal = ({ isOpen, onClose, children }) => {
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
return () => setMounted(false);
}, []);
if (!isOpen || !mounted) return null;
return createPortal(
<div className="modal-overlay" onClick={onClose}>
<div className="modal-content" onClick={e => e.stopPropagation()}>
{children}
</div>
</div>,
document.body
);
};
public/index.html에 별도 마운트 포인트를 만드는 방법도 있지만, 간단한 경우 document.body에 직접 렌더링하는 것으로 충분했다.
결과
z-index 스타일 충돌 없이 모달이 정상적으로 동작하게 되었다. Portal을 사용하면 이벤트 버블링도 React 트리를 따라가기 때문에 Context API와도 문제없이 호환됐다.
재택근무로 혼자 작업하는 시간이 많아지면서 이런 작은 이슈들을 정리해두는게 더 중요해진 것 같다.