Legacy
CorePortal
React Portal을 사용해 DOM 계층 외부에 자식을 렌더링하는 컴포넌트.
개요
CorePortal은 ReactDOM.createPortal을 래핑한 유틸리티 컴포넌트입니다. 자식 요소를 현재 React 트리가 아닌 별도의 DOM 컨테이너에 렌더링하므로, z-index 충돌이나 overflow 클리핑 문제를 피할 수 있습니다.
- 자동 컨테이너 생성 —
containerId에 해당하는<div>가 없으면 자동으로 생성해document.body에 붙임 containerId— 기본값'portal'. 기존 DOM 요소를 재사용하거나 새로 생성className/style— 포털 컨테이너<div>자체에 적용- SSR 안전 —
useEffect내부에서 DOM 접근, 서버에서는null반환
Usage
기본 사용법
<CorePortal containerId="my-portal"> <div style={{ padding: '16px', background: '#f0f0f0' }}> 포털로 렌더링된 내용 </div> </CorePortal>
기본 Container ID 사용
containerId를 생략하면 id가 'portal'인 컨테이너를 사용합니다.
<CorePortal> <div>기본 containerId "portal" 사용</div> </CorePortal>
모달과 함께 사용
레이아웃의 overflow: hidden 영향을 받지 않고 모달을 최상위에 렌더링합니다.
<CorePortal> <CoreModal size="md" title="포털 모달" handleClose={() => {}}> <div>모달 내용</div> </CoreModal> </CorePortal>
드롭다운과 함께 사용
조상 요소의 overflow 클리핑 없이 드롭다운을 원하는 위치에 띄웁니다.
import { useState, useRef } from 'react';
import { CorePortal, CoreDropdown } from '@featuring-corp/components';
function Example() {
const [open, setOpen] = useState(false);
const ref = useRef<HTMLButtonElement>(null);
return (
<>
<button ref={ref} onClick={() => setOpen(!open)}>
드롭다운 열기
</button>
{open && (
<CorePortal>
<CoreDropdown
open={open}
handler={setOpen}
placement="bottom-center"
targetRef={ref}
>
<div>드롭다운 내용</div>
</CoreDropdown>
</CorePortal>
)}
</>
);
}커스텀 Container ID
HTML에 미리 <div id="custom-portal"></div>가 있으면 해당 요소를 재사용합니다.
<CorePortal containerId="custom-portal"> <div>커스텀 포털 컨테이너 사용</div> </CorePortal>
Props
Prop
Type
스타일
CorePortal 자체는 별도의 시각 스타일을 갖지 않습니다. className과 style prop이 포털 컨테이너 <div>에 직접 적용되므로, 필요에 따라 소비자가 자유롭게 스타일을 지정합니다.
동작 방식 요약
- 컴포넌트 마운트 시
containerId로document.getElementById탐색 - 요소가 없으면
document.createElement('div')로 생성 후document.body.appendChild className/style이 있으면 해당 컨테이너에 적용ReactDOM.createPortal(children, container)로 자식 렌더링- 언마운트 시 컨테이너에 대한 참조를 해제 (컨테이너 자체는 유지)