Blog

테크

React로 모달 구현하기 - CreatePortal과 Dialog 비교

#Frontend#React#HTML5#Modal

2023-08-07

React로 모달 구현하기 - CreatePortal과 Dialog 비교
React로 모달 구현하기 - CreatePortal과 Dialog 비교

React로 모달 구현하기 - CreatePortal과 Dialog 비교

카테고리
테크
제품
바디닷
작성자
생성일
Aug 7, 2023 09:12 AM
생성자
마지막 수정시간
Last updated February 5, 2024
상태
완료
블로그게시
게시
태그
Frontend
React
HTML5
Modal
마지막 수정자
게시자
sokkanji
블로그카테고리
tech
업로드표시날짜
Aug 7, 2023
블로그_관련제품
bodydot
요약
createPortal과 HTML Dialog 요소를 비교하고 각 방법의 장단점과 사용 사례를 알아보세요.
블로그_이벤트

목차

  1. 시작하며
  1. createPortal 란?
  1. dialog element 란?
  1. 코드 비교
  1. 테스트
  1. 정리
 

시작하며

안녕하세요. 이번 글에서는 React를 사용하는 프로젝트에서 모달을 구현하는 방법으로 createPortaldialog element를 사용하여 모달을 구현하는 방법이 있습니다. 두 개의 방법 중에서 어떤 상황에서 무엇을 사용하면 더 좋을지를 알려드리기 위해 각 특징들에 대해 정리하고 설명드리고자 합니다.
 
 

createPortal 란?

  • React 에서 제공하는 기능입니다.
  • 모달 컴포넌트를 현재 컴포넌트의 DOM 트리에서 분리하여 별도의 DOM 노드에 렌더링합니다.
  • 모달을 최상위 레벨에서 렌더링하여 다른 요소들과 겹치지 않고 독립적으로 동작합니다.
  • React 프로젝트에서 많이 사용하는 방법입니다.
 
notion image
 
장단점
  • 장점
    • 엘리먼트 위치가 최상단에 있기 때문에, 모달 내부 상태 및 로직 관리하기에 용이합니다.
      • 기존에 사용하는 DOM 과 다른 DOM에서 렌더링을 하기 때문에 관리하기가 좋습니다.
    • 커스텀 모달을 구현하는 경우에 더 다양하게 스타일링 및 레이아웃 구현이 가능합니다.
  • 단점
    • 모달 외부 요소를 가리는 element(dimmed) 구현 필요합니다.
 
요약
React 프로젝트에서 유연한 커스텀 모달을 구현하는 데에 적합합니다.
 
 

dialog element 란?

  • HTML5에서 도입된 태그입니다.
  • <dialog> 를 사용하면 브라우저 내장 기능으로 모달을 구현 가능합니다.
    notion image
     
    장단점
    • 장점
      • 일관된 모달 스타일과 동작을 제공하여 접근성이 좋습니다.
      • 스크립트 없이 사용 가능합니다.
      • 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
    sokkanjiUpdated Jan 26, 2024
     
    모달을 확인하려면 아래 링크를 참고해 주세요.
     
     

    정리

    React를 사용하는 프로젝트 환경에서 단순한 안내 메세지와 확인 버튼이 있는 폼이 있는 모달을 구현할 계획이라면 dialog 태그를 사용하여 간단하게 구현하는 것이 좋고,
    복잡한 폼이 있는 모달이나 스타일이나 동작 제어에 관한 커스텀마이징이 필요한 모달인 경우에는 createPortal 로 구현하는 것이 좋아보입니다.
     
     
    참고한 아티클

    sokkanji

    관련된 이야기