포탈이란 실제 렌더링될 HTML의 내용을 다른 곳으로 옮기는 것이다.
이를 이용하여 주로 모달을 만드는데 사용한다.
모달의 실제 렌더링될 위치를 바꾸지만 실제 모달의 기능에는 어떠한 영향도 미치지 않는다.

포털을 사용하여 왼쪽의 코드 구조를 유지하면서 실제 DOM을 다른 곳에 렌더링할 수 있다.

즉, 위와 같이 실제 DOM에서 모달의 위치를 form 태그 옆에 있지 않게 할 수 있다.
실제 DOM에서 모달의 위치는 root div의 옆이며 body 태그의 직계 하위 컴포넌트로 이동하게 된다.
root div의 옆, body 태그의 직계 자식의 위치로 portal의 장소를 지정한다.
root를 여러개 만들어서 그 장소로 portal되도록 할 수 있다.
index.html
<body>
<div id="backdrop-root"></div>
<div id="overlay-root"></div>
<div id="root"></div>
</body>

Modal.js
import ReactDOM from 'react-dom'
const Backdrop = (props) => {
return <div onClick={props.onCancelModal} />
}
const ModalOverlay = (props) => {
return (
<>
<header>
<h2>{props.title}</h2>
</header>
<div>
<p>{props.message}</p>
</div>
<footer>
<button onClick={props.onCancelModal} >OK</button>
</footer>
</>
)
}
const Modal = (props) => {
return (
<>
{ReactDOM.createPortal(
<Backdrop onCancelModal={props.onCancelModal} />,
document.getElementId('backdrop-root')
)}
{ReactDOM.createPortal(
<ModalOverlay
title={props.title}
message={props.message}
onCancelModal={props.onCancelModal}
/>,
document.getElementId('overlay-root')
)}
</>
)
}
우선 portal로 렌더링될 위치를 옮기기 쉽게하기 위해 Modal컴포넌트의 배경을 담당할 Backdrop과 모달부분을 담당할 ModalOverlay를 다른 컴포넌트로 나누어 만들어 준다.
createPortal은 두가지 매개변수를 갖는다.
첫번째 인수는 포탈로 이동시킬 컴포넌트이며, 두번째 인수는 컴포넌트가 실제 렌더링될 장소를 가르키는 포인터이다.

index.js에서 렌더를 위해 선택한 Id로 렌더링 될 장소를 지정해 App컴포넌트를 렌더링 했던 것과 같은 로직이다.

결과적으로 실제 DOM을 살펴보면 root div의 옆, body 태그의 직계 자식의 위치로 portal의 장소로 지정하였고 이곳에 모달을 위치시켰음을 확인할 수 있다.