bread-gee 2023. 12. 6. 14:24
  • 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;