목차
- 시작하며
- createPortal 란?
- dialog element 란?
- 코드 비교
- 테스트
- 정리
시작하며
안녕하세요. 이번 글에서는 React를 사용하는 프로젝트에서 모달을 구현하는 방법으로
createPortal
나 dialog element
를 사용하여 모달을 구현하는 방법이 있습니다. 두 개의 방법 중에서 어떤 상황에서 무엇을 사용하면 더 좋을지를 알려드리기 위해 각 특징들에 대해 정리하고 설명드리고자 합니다. createPortal 란?
- React 에서 제공하는 기능입니다.
- 모달 컴포넌트를 현재 컴포넌트의 DOM 트리에서 분리하여 별도의 DOM 노드에 렌더링합니다.
- 모달을 최상위 레벨에서 렌더링하여 다른 요소들과 겹치지 않고 독립적으로 동작합니다.
- React 프로젝트에서 많이 사용하는 방법입니다.

장단점
- 장점
- 엘리먼트 위치가 최상단에 있기 때문에, 모달 내부 상태 및 로직 관리하기에 용이합니다.
- 커스텀 모달을 구현하는 경우에 더 다양하게 스타일링 및 레이아웃 구현이 가능합니다.
기존에 사용하는 DOM 과 다른 DOM에서 렌더링을 하기 때문에 관리하기가 좋습니다.
- 단점
- 모달 외부 요소를 가리는 element(dimmed) 구현 필요합니다.
요약
React 프로젝트에서 유연한 커스텀 모달을 구현하는 데에 적합합니다.
dialog element 란?
- HTML5에서 도입된 태그입니다.
<dialog>
를 사용하면 브라우저 내장 기능으로 모달을 구현 가능합니다.

장단점
- 장점
- 일관된 모달 스타일과 동작을 제공하여 접근성이 좋습니다.
- 스크립트 없이 사용 가능합니다.
open
속성 지원하여 모달 열기/닫기 기능을 간단하게 구현 가능합니다.- key 입력(esc, enter) 지원됩니다.
- 단점
- 모든 브라우저가
<dialog>
요소를 지원하지는 않습니다. - 기본 스타일이 적용되어 있어서 모달 스타일을 변경하려면
backdrop
같이 css 요소를 찾아서 변경해야하는 번거로움이 있을 수 있습니다. open
속성을 사용하면backdrop
적용이 되지 않습니다. (backdrop
는 모달 외부 요소를 가리는 어두운 배경)
dialog::backdrop { background: #ddd }
요약
브라우저 내장 기능을 활용하여 간단한 모달을 구현하는 데에 적합합니다.
코드 비교
createPortal
을 사용해서 모달 구현한 예시 코드// Modal.js import React from 'react'; import ReactDOM from 'react-dom'; const Modal = ({ children, onClose }) => { return ReactDOM.createPortal( <div className="modal"> <div className="modal-content"> {children} <button onClick={onClose}>Close</button> </div> </div>, document.getElementById('modal-root') ); }; export default Modal;
// App.js import React, { useState } from 'react'; import Modal from './Modal'; const App = () => { const [showModal, setShowModal] = useState(false); const handleOpenModal = () => { setShowModal(true); }; const handleCloseModal = () => { setShowModal(false); }; return ( <div> <button onClick={handleOpenModal}>Open Modal</button> {showModal && ( <Modal onClose={handleCloseModal}> <h2>Modal Content</h2> <p>This is a modal example using createPortal.</p> </Modal> )} </div> ); }; export default App;
<dialog>
를 사용해서 모달 구현한 예시 코드// App.js import React, { useRef } from 'react'; const App = () => { const dialogRef = useRef(); const handleOpenModal = () => { dialogRef.current.showModal(); }; const handleCloseModal = () => { dialogRef.current.close(); }; return ( <div> <button onClick={handleOpenModal}>Open Modal</button> <dialog ref={dialogRef}> <h2>Modal Content</h2> <p>This is a modal example using the dialog element tag.</p> <button onClick={handleCloseModal}>Close</button> </dialog> </div> ); }; export default App;
테스트
아래 레포지토리에서 코드를 확인하실 수 있습니다.
createPortal-vs-dialog-element
sokkanji • Updated Jan 26, 2024
모달을 확인하려면 아래 링크를 참고해 주세요.
정리
React를 사용하는 프로젝트 환경에서 단순한 안내 메세지와 확인 버튼이 있는 폼이 있는 모달을 구현할 계획이라면
dialog
태그를 사용하여 간단하게 구현하는 것이 좋고,복잡한 폼이 있는 모달이나 스타일이나 동작 제어에 관한 커스텀마이징이 필요한 모달인 경우에는
createPortal
로 구현하는 것이 좋아보입니다.참고한 아티클