Programming

[TIL] React Portal을 사용해 Modal 만들기

jay-dev 2023. 7. 12. 00:57

React Portal 사용 이유

  1. 유연한 구성: 리액트 포탈은 컴포넌트를 다른 DOM 위치로 이동시키기 때문에 UI 구성을 더욱 유연하게 할 수 있습니다.
    예를 들어, 모달(Modal) 창을 구현할 때 일반적으로는 모달 컴포넌트를 최상위 컴포넌트의 자식으로 추가해야 합니다. 하지만 리액트 포탈을 사용하면 모달 컴포넌트를 원하는 위치로 이동시킬 수 있으므로, 보다 복잡한 UI 구성도 쉽게 구현할 수 있습니다.
  2. 성능 최적화: 리액트 포탈은 컴포넌트의 렌더링 결과를 다른 DOM 위치로 이동시키는 기능을 제공하므로, 컴포넌트의 렌더링이 최적화될 수 있습니다. 예를 들어, 상위 컴포넌트에서 자식 컴포넌트를 렌더링하면서 상태(State)를 변경하면, 해당 컴포넌트와 그 자식 컴포넌트가 모두 다시 렌더링됩니다. 하지만 리액트 포탈을 사용하면 해당 컴포넌트와 그 자식 컴포넌트 중에서 변경된 부분만 렌더링되므로, 불필요한 렌더링을 최소화할 수 있습니다.
// index.html
<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <div id="portal"></div>   
</body>

index.html <body> 태그 안에 portal 추가

 

import Button from "../button/Button";
import { css, styled } from "styled-components";
import ReactDom from "react-dom";

const Modal = ({ children, handleOneButtonModal, handleTwoButtonModal, display }) => {
  return ReactDom.createPortal(
    <>
      <StModalBg onClick={handleOneButtonModal}></StModalBg>
      <StModal display={display}>
        <StDesc>{children}</StDesc>
        <StOneBtnContainer>
          <StOneBtn display={display} onClick={handleOneButtonModal}>
            X
          </StOneBtn>
        </StOneBtnContainer>
        <div>
          <StTwoBtn display={display}>
            <Button onClick={handleTwoButtonModal} size="small" pOrN="negative">
              닫기
            </Button>
            <Button onClick={handleTwoButtonModal} size="small" pOrN="primary">
              확인
            </Button>
          </StTwoBtn>
        </div>
      </StModal>
    </>,
    document.getElementById("portal")
  );
};

export default Modal;

사용할 Modal 컴포넌트에서

ReactDom을 import하고

 

return문에 ReactDom.createPortal

document.getElementById("portal") 추가

'Programming' 카테고리의 다른 글

[WIL] week5 회고  (0) 2023.07.17
[TIL] window.location / useNavigate 차이  (3) 2023.07.14
[TIL] React Query  (0) 2023.07.11
[TIL] React Hooks  (1) 2023.07.09
[WIL] week4 회고  (0) 2023.07.09