React Portal 을 이용하여 Modal 만들기.

change up·2024년 1월 2일
1

React Portal?

React Portal은 컴포넌트를 기존의 부모 컴포넌트의 DOM 계층구조가 아닌, 다른 위치의 DOM 노드로 렌더링할 수 있게 해주는 기능입니다.

DOM의 스타일 구조가 컴퓨터에 의해 이해되어 렌더링된다는 것은, 브라우저가 HTML과 CSS를 해석하여 픽셀 단위로 화면에 표시하는 과정을 말합니다. 이때, React Portal을 사용하면, 원하는 위치에 컴포넌트를 '직접' 렌더링할 수 있어서, 렌더링 트리에서 부모 컴포넌트 바깥에 렌더링하는 것을 가능하게 합니다. 이는 레이아웃이나 스타일링에 영향을 주는 중첩된 DOM 구조에서 벗어나 원하는 위치에 직접 UI를 배치할 수 있는 유연성을 제공합니다.

React Portal의 장점?

1.모달, 팝업, 툴팁 구현 용이성: 이러한 UI 요소들은 종종 애플리케이션의 다른 부분과 겹쳐서 표시됩니다. Portal을 사용하면, 이러한 요소들을 문서의 최상위에 렌더링할 수 있어, z-index와 같은 CSS 스타일링 문제를 쉽게 해결할 수 있습니다.

2.이벤트 버블링: Portal 내부에서 발생한 이벤트는 React 컴포넌트 트리에서 Portal을 사용하는 컴포넌트까지 버블링됩니다. 이는 Portal을 사용하더라도 React의 이벤트 시스템을 그대로 활용할 수 있음을 의미합니다.

3.부모 컴포넌트와의 독립성: 부모 컴포넌트의 CSS 스타일링이나 레이아웃에 영향을 받지 않고, 독립적인 UI 부분을 렌더링할 수 있습니다. 이는 복잡한 스타일링이나 레이아웃이 있는 애플리케이션에서 UI 충돌을 방지하는 데 도움이 됩니다.

4.성능 최적화: 특정 상황에서 Portal을 사용하면 불필요한 렌더링을 방지하고 성능을 향상시킬 수 있습니다. 예를 들어, 페이지의 깊은 곳에 위치한 컴포넌트에서 대규모 업데이트가 발생할 경우, Portal을 통해 이를 독립적으로 관리함으로써 전체 페이지 렌더링을 방지할 수 있습니다.

5.유연성: Portal을 사용하면 어떤 DOM 노드로든 컴포넌트를 렌더링할 수 있어, 애플리케이션의 구조와 상관없이 UI를 유연하게 구성할 수 있습니다. 이는 대규모 애플리케이션 또는 특정 레이아웃 요구 사항이 있는 애플리케이션에서 특히 유용합니다.

React Portal을 활용해서 코드 적용.

-> 리액트 포탈을 사용하여 모달을 생성함으로써 , 재사용성을 높히고 DOM-tree 상의 부포-자식 컴포넌트가 독립적으로 구조를 유지하도록 하였다.또한 모달생성시 발생 할 수 있는 오버레이문제를 해결하기 위해 적용했다.

1)create portal: ReactDom.createPortal 메소드를 사용하여 컴포넌트를 "포털한다(portal)" 하여 React 컴포넌트 트리의 현재 위치와는 다른, children으로 받은 컨텐츠를 모달로서 페이지의 특정 위치(DOM 요소 el 내부)에 렌더링하는 역할을 한다.

import ReactDom from "react-dom";

export const ModalPortal = ({children}) => {
    const el = document.getElementById("modal");
    return ReactDom.createPortal(children,el);
};

2)모달 컴포넌트 생성

import React from "react";
import * as S from "./style/MyModal.style"

export const MyModal = ({message, onClose ,onConfirm}) => {
    return (
        <S.MyModal>
          <S.Mask onClick={onClose}></S.Mask>
          <S.ModalBody>
            <S.ModalContent >
              <p>{message}</p>
              <button onClick={onClose}>취소</button>
              <button onClick={onConfirm}>확인</button>
            </S.ModalContent>
          </S.ModalBody>
        </S.MyModal>
      );
    };

3)페이지에 적용 : modal info 상태 변수 정의후 모달이 보여질시 표시되어질 정보를 정의하고 , 댓글삭제및 게시글 삭제 메소드 함수를 생성 후 삼항 연산자를이용하여 둘중의 하나가 표시되고 실행되도록 코드를 정리하였다.

const [modalInfo, setModalInfo] = useState({ show: false, type: '', message: '', action: null });

    const showModal = (type, message, action) => {
        setModalInfo({ show: true, type, message, action });
    };
    const closeModal = () => {
        setModalInfo({ ...modalInfo, show: false });
    };
  const handleDelete = () => {
        showModal('deletePost', '정말로 이 게시글을 삭제하시겠습니까?', fetchPostDelete);
    };

    const handleCommentDelete = (commentId) => {
        const action = () => fetchCommentDelete(commentId);
        showModal('deleteComment', '정말로 댓글을 삭제하시겠습니까?', action);
    };
 {modalInfo.show && (
                <ModalPortal>
                <MyModal
                    title={modalInfo.type === 'deleteComment' ? '댓글 삭제' : '게시글 삭제'}
                    message={modalInfo.message}
                    onConfirm={() => {
                        modalInfo.action && modalInfo.action();
                        closeModal(); 
                    }}
                    onClose={closeModal}
                />
                </ModalPortal>

참고 블로그 : 박히밍 개발 블로그

profile
새싹이

0개의 댓글