리액트 프로젝트 구성요소를 자세히 살펴보면 index.js에서 아래와 같은 코드를 볼 수 있다.
ReactDOM.render(<App />, document.getElementById("root"));
이것은 public폴더 index.html파일의 id = "root"인 요소의 자식으로 App 컴포넌트를 렌더링 하는 코드이다. 그런데 어떠한 이유로 부모 컴포넌트 바깥에서 자식 컴포넌트를 렌더링 하는 경우도 생기는데 예를 들면 모달 같은 경우가 있겠다.
📌 사용법
ReactDOM.render() 함수로 인해 root의 자식 요소로 배치되는데 외부에 존재하는 DOM 노드가 React App DOM의 계층 안에 존재하는 것처럼 컴포넌트를 연결해주는 포탈 기능을 제공한다.
ReactDOM.createPortal(<컴포넌트 />, 배치할 DOM 식별자)
부모 외부의 구성 요소를 렌더링하기 위해 ReactDOM.createPortal()을 사용하여 원하는 위치에 렌더링 할 수 있다.
📌 사용예시
<html>
<body>
<div id="app-root"></div>
<div id="modal-root"></div>
</body>
</html>
modal을 app의 자식 요소가 아닌 형제 요소로 렌더링하기 위해 id="modal-root"를 생성
src/App.js
import { useState } from "react";
import Modal from "./Modal";
import "./styles.scss";
export default function App({ members }) {
const [showModal, setShowModal] = useState(false);
const handleModal = () => setShowModal(!showModal);
const modal = showModal ? (
<Modal handleClose={handleModal}>
<>
<h1>Thanks for clicking!</h1>
<p>This is being rendered inside the #modal div, {members}.</p>
<button onClick={handleModal}>Close</button>
</>
</Modal>
) : null;
return (
<div className="app">
<h1>My website</h1>
<p>Welcome to my website {members}!</p>
<button onClick={handleModal}>Show modal</button>
{modal}
</div>
);
}
button을 클릭해 showModal이 true면 Modal 컴포넌트가 렌더링된다.
src/Modal.js
import ReactDOM from "react-dom";
import "./styles.scss";
export default function Modal({ children, handleClose }) {
const modalElement = document.getElementById("modal-root");
return ReactDOM.createPortal(
<div className="c-modal">
<div className="c-modal__veil" onClick={handleClose} />
<div className="c-modal__box">
<button className="c-modal__close" onClick={handleClose}>
X
</button>
{children}
</div>
</div>,
modalElement
);
}
ReactDOM.createPortal()을 사용하여 id = "modal-root"인 요소의 자식으로 렌더링하기 위해 JSX 코드를 createPortal의 첫번째 인자로 넣어준다.
📌 portals 사용 결과
'Programming > React' 카테고리의 다른 글
배열 key props (0) | 2023.04.28 |
---|---|
useState의 렌더링, 함수형 업데이트 (0) | 2023.04.28 |
React 클래스 컴포넌트 이벤트 처리와 this (0) | 2021.09.22 |
React PureComponent를 알아보자! (0) | 2021.09.19 |
React 컴포넌트 라이프사이클 (0) | 2021.09.11 |