리액트 createPortal

한태동·2024년 8월 11일

🔎 CreatePortal이란

  • React 에서 제공하는 기능.
  • 모달 컴포넌트를 현재 컴포넌트의 DOM 트리에서 분리하여 별도의 DOM 노드에 렌더링합니다.
  • 모달을 최상위 레벨에서 렌더링하여 다른 요소들과 겹치지 않고 독립적으로 동작합니다.
  • React 프로젝트에서 많이 사용하는 방법입니다.

🖥️ 사용법

다음은 리액트 공식 문서에 명시된 createPortal 기본 코드이다.

<div>
  <SomeComponent />
  {createPortal(children, domNode, key?)}
</div>

포탈을 생성하기 위해서, JSX와 포탈이 렌더링 되야하는 DOM node를 매개 변수로 전달해야 한다.

import { createPortal } from 'react-dom';

// ...

<div>
  <p>This child is placed in the parent div.</p>
  {createPortal(
    <p>This child is placed in the document body.</p>,
    document.body
  )}
</div>

위 코드에서 createPortal 에 JSX인 <p>This child is placed in the document body.</p> 를 첫번째 매개 변수로 지정했고, DOM node인 document.body 를 두 번째 매개변수로 지정했다.

따라서 document.body 에 해당하는 부분에 첫 번째 매개변수인 JSX가 렌더링 될 것이다. 포탈은 렌더링된 요소의 물리적 위치만 바꾸고, 그 요소가 React 애플리케이션 내부에서 어떻게 동작하는지(부모-자식 관계, 컨텍스트 접근 등)는 그대로 유지한다.

🧑🏻‍💻 프로젝트 내 실제 사용

본 프로젝트에서 모든 페이지의 우측 하단의 채팅 버튼을 클릭하면 모달창이 열리게 하였다. 구현 화면은 맨 위와 같다. 다음은 코드 작성 과정이다.

1) 포탈 렌더링되기 위한 DOM node 작성

createPortal 의 두 번째 매개변수인 DOM node는 document.getElementById() 등으로 접근 가능한 실제로 존재하는 요소여야 한다. index.html 의 body에 modal이라는 id를 가진 DOM node인 div를 작성했다.

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

2) createPortal 코드 작성

모달코드.png

리액트 공식 문서의 createPortal 기본 사용법을 참고해 페이지의 우측 하단에 있는 ChatButton 의 클릭 이벤트가 활성화되면 useState를 통해 open으로 바꿔 createPortal 함수가 실행되도록 하였다. 첫 번째 파라미터는 JSX 요소인 컴포넌트 <ChatModal /> 이고 두 번째 파라미터는 index.html 에서 설정한 DOM node 인 id가 ‘modal’인 div 이다.

3) 모달창(ChatModal) 꾸미기

모달화면.png

createPortal 의 첫 번째 파라미터이자 실질적인 모달창 화면으로 보여질 ChatModal 컴포넌트이다.

모달화면css.png

position: fixed는 요소를 뷰포트(viewport)에 상대적으로 고정시키다. 즉, 스크롤과 상관없이 항상 화면의 같은 위치에 있게 한다. top, bottom, left, right 속성을 모두 0으로 지정해 요소를 뷰포트 전체를 차지하게 만들었다. 그 후 display: flex를 와 align-itemsjustify-content를 center로 지정하여 뷰포트 가운데에 모달창을 고정시켰다.

0개의 댓글