React Portals 리액트 포탈

이온·2023년 9월 23일
0

react

목록 보기
4/6
post-thumbnail

1. modal이 그냥 컴포넌트일 경우 문제점

두개의 컴포넌트가 나란히 프래그먼트로 둘러싸여 있다.
문제는 없지만 DOM에 랜더링 되는 이 모달 코드는 모달처럼 보이긴 한다.
하지만 의미적으로 보거나, 간결한 HTML구조를 갖췄는지의 관점으로 보면 별로 좋지 않다.
왜냐면 '모달'은 기본적으로 전체 페이지 위에 표시되는 오버레이이기 때문이다. 당연히 다른 모든것 위에 있다. 따라서 이것이 만약 다른 코드 안에 중첩되어 있다면 기술적으로는 작동할 수 있어도 좋은 코드, 좋은 구조는 아닌 셈이다. 또 스타일링이나 접근성의 관점에서 문제가 생길 가능성이 크다.
비슷하게 사이드 드로어나 다이얼로그같은 일반적인 모든 종류의 오버레이나 관련 텀포넌트에도 해당되는 문제이다.
쉽게 말하자면 버튼 태그를 그냥 div태그로 만들어 작동시키는 것과 비슷하다.

2. react portal의 사용


여기서는 모달이 폼 옆에 있지 않는 것이다.

<!-- 📍public>index.html -->

<!-- 컴포넌트를 이동시킬 장소를 표시한다 --><div id="backdrop-root"></div><div id="overlay-root"></div>
    <div id="root"></div>
// 📍src>components>ErrorModal.js
import React from "react";
import { ReactDOM } from "react-dom";

// 모달을 두개의 컴포넌트로 분리하기const Backdrop = (props) => {
  return <div onClick={props.onConfirm} />;
};const ModalOverlay = (props) => {
  return (
    <Card>
      ...
    </Card>
  );
};

const ErrorModal = (props) => {
  return (
    <React.Fragment>{ReactDOM.createPortal(
        <Backdrop onConfirm={props.onConfirm} />,
        document.getElementById("backdrop-root")
      )}
    </React.Fragment>
  );
};

export default ErrorModal;

실제 DOM의 다른 위치로 이동시키기 위해 react-dom을 사용한다.
createPortal 메소드를 호출한다. 두가지 인자를 받는데, 첫번째는 렌더링 되어야하는 리액트 노드이다.(JSX로 작성).
두번째 인자는 포인터이다. 이 요소가 랜더링 되어야하는 실제 DOM의 컨테이너를 가리키는 포인터이다. 이를 위해 DOM API를 사용한다.
랜더링 하려는 HTML 내용을 다른 장소로 이동시키는 것이다.

profile
👩🏻‍💻

0개의 댓글