
Portal은 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링하는 방법을 제공합니다.
모달은 특정 HTML 안이 아니라 모든 컴포넌트의 바깥에 있어야 합니다. 따라서 모달 엘리먼트를 바깥으로 빼내야 하는데, 이 때 사용하는게 createPortal 메서드 입니다. 해당 메서드는 react-dom이 필요합니다.
ReactDOM.createPortal(child, container)
첫 번째 인자(child)는 엘리먼트, 문자열, 혹은 fragment와 같은 어떤 종류이든 렌더링할 수 있는 React 자식입니다. 두 번째 인자(container)는 DOM 엘리먼트입니다.
import React from 'react';
import ReactDOM from 'react-dom';
const Backdrop = (props) => {
return <div className={classes.backdrop} onClick={props.onConfirm} />;
};
const ModalOverlay = (props) => {
return (
<Card className={classes.modal}>
<header className={classes.header}>
<h2>{props.title}</h2>
</header>
<div className={classes.content}>
<p>{props.message}</p>
</div>
<footer className={classes.actions}>
<Button onClick={props.onConfirm}>Okay</Button>
</footer>
</Card>
);
};
const ErrorModal = (props) => {
return (
<React.Fragment>
{ReactDOM.createPortal(
<Backdrop onConfirm={props.onConfirm} />,
document.getElementById('backdrop-root')
)}
{ReactDOM.createPortal(
<ModalOverlay
title={props.title}
message={props.message}
onConfirm={props.onConfirm}
/>,
document.getElementById('overlay-root')
)}
</React.Fragment>
);
};
해당 예시는 루트 div 옆에 modal과 backdrop div 태그를 미리 만들어둬야 합니다.
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="backdrop-root"></div>
<div id="overlay-root"></div>
<div id="root"></div>
</body>
index.html
기존에는 redux로 바깥 컴포넌트를 활성화/비활성화 하는 방법을 통해 모달의 위치를 조정했는데, 해당 방법을 사용해 쉽게 모달을 제어할 수 있었습니다.
정보에 감사드립니다.