빵 입니다.
Portal 본문
- DOM 트리의 특정 위치에 컴포넌트를 렌더링하기 위한 API
- React 애플리케이션에서 모든 컴포넌트는 동일한 부모 컴포넌트 내에서 렌더링되는데,
특정 UI 요소를 다른 DOM 요소의 위치로 렌더링해야 하는 경우엔 ReactDOM.createPortal을 사용한다.
(특히 모달, 툴팁, 드롭다운 메뉴 등의 UI 요소를 더 상위 수준의 DOM 노드에 렌더링하려는 경우에 효과적이다.) - Portal은 React 컴포넌트 트리를 따라가는 것이 아니라 다른 DOM 위치로 React 컴포넌트를 렌더링하는 데 사용되기 때문에 react-dom에서 제공하는 createPortal을 이용해 만든다.
- createPortal 함수는 첫 번째 매개변수로 렌더링할 React 요소와 두 번째 매개변수로 해당 요소를 삽입할 DOM 요소를 받는다.
🔥Vue의 teleport 역할
📌 createPortal 사용 예시
{ReactDOM.createPortal(
{/* 렌더링할 React 요소 */}
<Modal onClose={handleCloseModal}>
<h1>Modal Content</h1>
</Modal>,
{/* 해당 요소를 삽입할 DOM 요소 */}
document.getElementById('modal-root')
)}
📌 "두 번째 매개변수로 해당 요소를 삽입할 DOM 요소"를 미리 정의해야 한다.
<div id="modal-root"></div>
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>React App</title>
</head>
<body>
<div id="root"></div>
<div id="modal-root"></div>
</body>
</html>
🔥전체 코드 예시
더보기
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
const Backdrop = ({ onClose }) => {
return <div className="backdrop" onClick={onClose}></div>;
};
const Modal = ({ children, onClose }) => {
return (
<>
<Backdrop onClose={onClose} />
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
{children}
<button onClick={onClose}>Close</button>
</div>
</>
);
};
const App = () => {
const [modalOpen, setModalOpen] = useState(false);
const handleOpenModal = () => {
setModalOpen(true);
};
const handleCloseModal = () => {
setModalOpen(false);
};
return (
<div>
<button onClick={handleOpenModal}>Open Modal</button>
{modalOpen && (
<>
{ReactDOM.createPortal(
<Modal onClose={handleCloseModal}>
<h1>Modal Content</h1>
</Modal>,
document.getElementById('modal-root')
)}
</>
)}
</div>
);
};
export default App;
'프론트엔드 > React' 카테고리의 다른 글
useEffect() (0) | 2023.12.13 |
---|---|
useRef() (0) | 2023.12.06 |
CSS 스타일 설정 방법 (0) | 2023.12.06 |
react와 react-dom과 react-native (0) | 2023.12.06 |
조건부 렌더링 (0) | 2023.12.05 |
Comments