[TIL] Portal & 모달창

이현동·2023년 2월 15일
0

TIL

목록 보기
32/59

Modal

모달창을 만들기 위해서 Portal을 이용해 만들어보려고 한다.
"리액트 공식 문서에서는 Portal은 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링하는 최고의 방법을 제공한다." 라고 써있다.

ReactDOM.createPortal(child, container)

첫 번째 인자(child)는 엘리먼트, 문자열, 혹은 fragment와 같은 어떤 종류든 렌더링할 수 있는 React 자식이고, 두 번째 인자(container)는 DOM 엘리먼트를 말한다. 즉, child를 렌더링 할 DOM Element를 말한다.

...

<div id="root"></div>
<!-- createPotal을 사용해 Modal 만들기를 위해 DOM element를 추가 -->
<div id="modal"></div>

...

public에 있는 index.html에 새로운 div에 이제 portal로 접근해서 자식 컴포넌트를 생성하는 것이다.

import React from "react";
import { createPortal } from "react-dom";

function ModalContainer({ children }) {
  return createPortal(<>{children}</>, document.getElementById("modal"));
}

export default ModalContainer;

creatPortal을 만들어서 이제 Modal을 감쌀 것이다.


function ModalContainer() {
...
  return (
    <>
		...
        <ModalPortal>
          {isOpen && (
            <ModalOverlay>
                <ModalBox>
                 content
                </ModalBox>
            </ModalOverlay>
          )}
          {isOpen1 && (
             <ModalOverlay>
               <ModalWrapper>
                 <ModalBox>
                   content
                 </ModalBox>
			   </ModalWrapper>
            </ModalOverlay>
          )}
        </ModalPortal>
    </>
  );
}

const ModalOverlay = styled.div`
  background-color: rgba(0, 0, 0, 0.5);
  position: fixed;
  inset: 0px;
  width: 100%;
  height: 100vh;
`;

const ModalWrapper = styled.div`
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
`;

const Modal = styled.div`
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 31.25rem;
  height: 19rem;
  padding: 1.25rem;
  border: 1px solid black;
  border-radius: 1.25rem;
  background-color: white;
`;

export default ModalContainer;

Modal Portal 컴포넌트 안의 children이 이제 public>index.html에 있는 <div id="modal"></div> 내부에 생성되게 된다. 다음은 아래 블로그를 따라서 모달창 외부 클릭을 해서 닫기에 대해서 알아볼 것이다. :)


참고자료

react portal을 사용한 모달창 만들기, 하루 기록

profile
https://hdlee.dev

0개의 댓글