react에서 부모 컴포넌트의 DOM 계층 밖에 DOM노드로 자식을 렌더링 하는방법이다.
간단한 예제를 통해 알아보자
// index.tsx
const rootElement = document.getElementById('root');
const root = createRoot(rootElement);
root.render(<Home/>);
// Portal.tsx
export const Portal = ({children}) => {
const root = document.getElementById('Modal');
return createPortal(children, root);
};
// Home.page.tsx
export const Home = () => {
return (
<div>
<Parent />
</div>
);
};
// Parent.tsx
export const Parent = () => {
return (
<div className="parent">
<h1>I'm parent</h1>
<Child />
</div>
);
};
// Child.tsx
export const Child = () => {
return (
<Portal>
<h2>I'm Child</h2>
</Portal>
);
};
이러한 구조의 파일이라고 가정했을 때
컴포넌트 구조 상 Parent
아래에 Child
가 있어야 할 것 같지만 그렇지 않고 실제로 렌더링하면 아래와 같이 Portal
컴포넌트가 #root
의 바로 하위 요소로 랜더링 된 것을 확인할 수 있다.
<body>
<div id="root"></div>
<div id="modal"></div> // 추가해줌
</body>
/// Modal.js
// 사용하려는 컴포넌트에 reactDom import해주기
import reactDom from "react-dom"
// Modal이 렌더링될 위치 가져오기
const portalElement = document.getElementById("modal");
ReactDOM.createPortal()함수는 두가지 인수를 받는다.
첫번째 인수는 랜더링 될 요소들, 두번째는 첫번째 요소가 랜더링 될 위치를 가리킨다.
import React from "react";
import reactDom from "react-dom"
const portalElement = document.getElementById("modal");
const Modal = (props) => {
return (
<>
{
ReactDOM.createPortal(
<Backdrop onClose={props.onClose} />,
portalElement)
}
{
ReactDOM.createPortal(
<ModalOverlay>{props.children}</ModalOverlay>,
portalElement)
}
</>
);
};
export default Modal;
<Modal onClose={handleModal}>
//... 내부 내용
</Modal>