React - Portals 로 모달만들기

Moolbum·2022년 8월 17일
0

React

목록 보기
17/23
post-thumbnail

Portals

React에서 제공하는 Portal은 UI를 어디에서 렌더링 시킬지 DOM을 사전에 선택하여 부모컴포넌트 바깥에서 렌더링 할 수 있도록 해줍니다.

  • child (첫번째인자) : ReactChildren
  • container (두번째인자) : DOM 엘리먼트
ReactDOM.createPortal(child, container)

사용방법

1. html id 추가

react프로젝트의 html에서 기본적으로 제공하는 index.html 에서 코드를 추가합니다.

  • react에서는 index.html에 추가하지만 next는 _document에서 추가할 수 있습니다.
// index.html
<div id="root"></div>
<div id="modal"></div> // id가 modal인 div추가

2. modal Portals 컴포넌트 생성

두번째 인자에는 DOM오브젝트가 들어가야 하므로 첫번째 단계에서 만들었던 id인 modal을 참조합니다.

// ModalPortal.js
import ReactDOM from "react-dom";

const ModalPortal = ({ children }) => {
  const el = document.getElementById("modal");
  return ReactDOM.createPortal(children, el);
};

export default ModalPortal;

3. modal 컴포넌트 생성

자신이 사용하고자 하는 모달 컴포넌트를 만들어줍니다.

// Modal.js
import React from "react";
import "./Modal.css";

const Modal = ({ onClose }) => {
  return (
    <div className="Modal">
      <div className="content">
        <h3>모달</h3>
        <p>궁시렁 궁시렁</p>
        <button onClick={onClose}>닫기</button>
      </div>
    </div>
  );
};

export default Modal;

css
.Modal {
  background: rgba(0, 0, 0, 0.25);
  position: fixed;
  left: 0;
  top: 0;
  height: 100%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.Modal .content {
  background: white;
  padding: 1rem;
  width: 400px;
  height: auto;
}

4. 모달 렌더링

사용하고자 하는 컴포넌트에서 ModalPortal를 이용해 Modal 을 감싸 자식 컴포넌트로 만들면 Portal 적용이 완료됩니다.

import React from "react";
import MyModal from "./MyModal";
import ModalPortal from "./ModalPortal";
import "./App.css";

const App = () => {
  const [modal, setModal] = React.useState(false);

  const handleCloseModal = () => {
    setModal(false);
  };

  const handleOpenModal = () => {
    setModal(true);
  };

  return (
    <div className="App">
      <h1>React Portals</h1>
      <button onClick={handleOpenModal}>모달 열기</button>
      
      {modal && (
        <ModalPortal>
          <MyModal onClose={handleCloseModal} />
        </ModalPortal>
      )}
    </div>
  );
};

export default App;

벨로퍼트 React Portal
React 공식문서

profile
Junior Front-End Developer 👨‍💻

0개의 댓글