
리액트로 모달(Modal)이나 툴팁(Tooltip)을 만들다 보면, 분명 z-index를 9999로 줬는데도 배경 뒤로 숨거나 부모 박스 안에서 잘려 보이는 현상을 겪을 수 있다
이때 필요한 것이 바로 createPortal이다!
createPortal이란?보통 리액트 컴포넌트는 부모 컴포넌트의 DOM 구조 안에 렌더링된다. 하지만 createPortal을 사용하면 컴포넌트의 논리적 위치(코드 위치)는 유지하면서, 물리적 위치(실제 그려지는 곳)만 다른 DOM 노드로 옮길 수 있다.
z-index, overflow: hidden, transform 설정이 있으면 자식인 모달은 그 영향을 받는다. 포탈을 쓰면 <body> 직계 자식으로 보낼 수 있어 이런 제약에서 자유롭다.index.html)<div id="root"></div>
<div id="modal-root"></div>
react-dom에서 제공하는 createPortal을 사용
import { createPortal } from 'react-dom;
function Modal({ children }) {
const mountNode = document.getElementById('modal-root');
if (!mountNode) return null;
return createPortal(
<div className="modal-overlay">
<div className="modal-content">{children}</div>
</div>,
mountNode // 👈 어디로 보낼지 결정
);
}
코드 위치는 상관없이 부모 컴포넌트 어디서든 호출
function CommunityPage() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<h1>자유게시판</h1>
<button onClick={() => setIsOpen(true)}>글쓰기</button>
{/* 화면상으로는 modal-root에 그려지지만, 로직은 여기서 관리! */}
{isOpen && <Modal>게시글 작성 폼입니다.</Modal>}
</div>
);
}
DOM을 독립시켜 주는 것이 포탈의 핵심!
DOM 독립이라니~~ 대한독립만세입니다~~ 🇰🇷