Portal은 부모 컴포넌트의 Dom 계층 구조 바깥에 있는 Dom 노드로 자식을 렌더링하는 방법을 제공한다.
=> 리액트 포탈을 사용하면 독립적인 위치에서 렌더링하기 때문에 DOM 계층 구조와 상관없이 편리하게 사용이 가능하다.(기존 컴포넌트의 구조에 영향을 주지 않는다.)
=> 따라서 스타일링 하기 간편하고 독립된 스타일링을 통해 유지보수성이 좋아지고 CSS 충돌이 방지된다.
Portal을 사용하면 React 컴포넌트 트리 내의 특정 부분에서 실제로는 DOM 트리의 다른 위치에 렌더링할 수 있다.
이로 인해 모달, 툴팁, 드롭다운 등과 같은 UI 요소를 더 쉽게 구현할 수 있다.
Portal을 통해 렌더링된 컴포넌트는 원래 위치의 컨텍스트를 유지한다.
이는 상태 관리, 테마, 언어 등과 같은 컨텍스트 값이 포탈로 렌더링된 컴포넌트에서도 동일하게 유지된다는 것
Portal을 사용하면 DOM 트리의 특정 부분에 직접 접근하고 조작할 수 있다. 이를 통해 특정 스타일링이나 위치 조정이 필요한 UI 요소를 더욱 정교하게 관리할 수 있다.
포털을 사용하면 모달이나 오버레이와 같은 요소가 DOM 트리의 최상위에 렌더링되기 때문에 접근성 관리가 용이해진다.
화면 리더기나 포커스 관리 측면에서도 유리하다.
modal-root라는 추가적인 DOM 요소를 HTML 파일에 만든다. 이 요소는 모달을 렌더링할 컨테이너 역할을 한다.
<!DOCTYPE html>
<html>
<head>
<title>React Portal Example</title>
</head>
<body>
<div id="root"></div>
<div id="modal-root"></div>
</body>
</html>
Modal : ReactDOM.createPortal을 사용하여 modal-root에 모달 내용을 렌더링한다. isShowing이 true일 때만 모달이 보이도록 조건부 렌더링을 한다.
App : 버튼 클릭으로 모달의 보이기/숨기기를 제어한다. 모달이 보이면 Modal 컴포넌트를 통해 포털을 사용하여 modal-root에 렌더링된다.
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
// 모달 컴포넌트
const Modal = ({ isShowing, hide }) => {
if (!isShowing) {
return null;
}
return ReactDOM.createPortal(
<div className="modal">
<div className="modal-content">
<button onClick={hide}>Close</button>
<div>This is a modal!</div>
</div>
</div>,
document.getElementById('modal-root')
);
};
// 메인 컴포넌트
const App = () => {
const [isModalShowing, setIsModalShowing] = useState(false);
const showModal = () => {
setIsModalShowing(true);
};
const hideModal = () => {
setIsModalShowing(false);
};
return (
<div>
<h1>React Portal Example</h1>
<button onClick={showModal}>Show Modal</button>
<Modal isShowing={isModalShowing} hide={hideModal} />
</div>
);
};
export default App;