리액트 Portal을 사용해 모달창을 생성하자

modi·2023년 5월 19일
0

React

목록 보기
2/2
post-thumbnail

프론트엔드 개발자라면 누구나 한 번은 모달창을 구현하게 된다! 모달이라는 용어를 들어보지 않았더라도, 아래 이미지를 본다면 아~ 이거?라고 누구나 할 정도로 웹에 많이 사용된다.

모달창이란?
웹에서 새 창을 띄우는 팝업창과 달리 같은 브라우저 내부에서 상위 레이어를 띄우는 방식을 사용하는 창이다.

많은 사용자에게 익숙한 만큼 프론트엔드 개발자라면 당연히 모달창을 구현할 수 있어야 한다. 이번 포스팅에서 기존에 내가 모달창을 생성하는 방식현재 생각하는 최적의 방법인 Portal을 비교하려고 한다.


기존 모달창


기존 방식으로 구현한 모달 컴포넌트다. opentrue일 때 모달창이 화면 중간에 나타난다. useOutsideClick 훅을 사용해 모달창 외부를 클릭하면 모달창이 닫히게 해주었다.

버튼을 클릭하면 isModalOpen의 상태가 true로 변하고, 모달창이 열리게 된다.

기존 모달창의 문제점

기존의 모달창은 부모 컴포넌트로부터 style 상속이 이루어진다.
작동에는 문제가 없다고 해도, overflow: hidden이나 z-index을 사용해 부모 컴포넌트로부터 상속된 style을 변경하는 것이 여간 귀찮은 일이 아니다.

Portal이란?

Portal은 오직 노드의 물리적 배치를 변경한다.

Portal을 제외한 다른 방식으로 (기존 방법) Portal에 렌더링하려는 JSX (모달창 내부 컴포넌트)는, 렌더링되는 React 컴포넌트의 자식 노드의 역할을 한다.

  • 자식 컴포넌트는 부모 트리가 제공하는 컨텍스트에 접근 가능
  • 이벤트는 React 트리에 따라 자식에서 부모로 버블업

Portal의 특징

  • Portal을 사용하면 당신의 컴포넌트를 DOM의 다른 위치로 렌더링할 수 있다. 이를 통해 당신의 컴포넌트는 부모로부터 탈출 할 수 있다.

  • Portal의 이벤트는 DOM 트리가 아닌 React 트리에 따라 전파되기 때문에, 이벤트 버블링은 정상적으로 작동한다.

  • Portal을 사용해 자식 엘리먼트를 렌더링할 때, 리액트가 자식 엘리먼트의 수명 주기를 제어할 수 있다.

  • Portal은 HTML DOM 구조에만 영향을 끼치며, React 컴포넌트 트리에는 영향을 미치지 않는다.

Portal을 활용한 모달창

index.html

  <body>
    <div id="root"></div>
    <div id="modal"></div>
    <script type="module" src="./src/main.jsx"></script>
  </body>

먼저 body에 id가 modal인 엘리먼트을 만든다.

createPortal(children, domNode, key?)을 통해 우리가 원하는 JSX(children)를 id="modal"을 가진 DOM 엘리먼트에 렌더링할 수 있다.

기존 모달창을 ModalPortalchildren으로 전달하면 Portal을 사용한 모달창이 된다.

결론

Portal을 사용해 기존 DOM(root)이 아닌 외부 DOM에서 엘리먼트를 그릴 수 있다. 이를 통해 엘리먼트는 부모로부터 CSS 상속을 받지 않는다. 그럼에도 이벤트 버블링은 React 트리로 전파되어 정상적으로 작동한다. CSS 상속을 피하고 싶은 모달창을 구현할 때 매우 유용하다!

참고자료

리액트 - Portals 를 통한 부모 컴포넌트의 외부 DOM 에 컴포넌트 렌더링하기

Portals

createPortal

Understanding React Portals and Its Use-Cases

profile
FE 개발자 취업 준비의 준비생

0개의 댓글