포털(Portal)은 자식 요소를 부모 컴포넌트의 DOM(Document Object Model) 계층 밖에 있는 다른 DOM 노드에 렌더하는 React 기능이다(createPortal(child, container)). DOM 위치만 옮겨지고 React 트리에서의 위치는 그대로다.
function Modal({ children }) {
return createPortal(<div className="modal">{children}</div>, document.body)
}- 주 용도: 모달, 툴팁, 드롭다운처럼 부모의
overflow: hidden이나 쌓임 맥락(Stacking Context)에 잘리면 안 되는 오버레이(쌓임 순서와 z-index, 모달과 다이얼로그) - Context는 그대로 동작한다. React 트리상 원래 위치에 있기 때문이다
- 이벤트는 React 트리를 따라 버블링한다. body로 옮겨진 버튼을 클릭해도 원래 부모의
onClick이 실행된다. DOM 기준으로 생각하면 놀라는 지점이다(이벤트 버블링·캡처링과 위임) - CSS(Cascading Style Sheets)는 DOM 기준이다. 부모의 상속 스타일이 적용되지 않으니 필요한 스타일은 포털 안에서 준다. 여러 포털이 겹치면 z-index도 직접 관리한다
- 대상 노드가 실제로 있는지 확인하고, 직접 만든 컨테이너는 정리 함수에서 제거한다
- 모달이라면 포커스 가두기(Focus Trap), Esc 닫기, ARIA(Accessible Rich Internet Applications) 속성 같은 접근성은 직접 챙겨야 한다. 요즘은 네이티브
dialog요소도 대안이다