React - Modal 관리

Gavri·2023년 1월 24일
0

React

목록 보기
4/5

개요

리액트 모달 관리 방법에 대해 정리한 글입니다.

React-Modal (기본)


const App= () =>{
  const [isModal,setIsModal] = useState(false);
  return isModal ? <Component /> : null;
}

장점

  • 직관적임
  • 한 컴포넌트 내에서 로직을 넣어 줄 수 있기에 모달과 컴포넌트간의 이벤트 교환이 간단함
<Modal onClose={()=>setIsShow(false)} />

단점

  • 직관적인 반면 그만큼 코드 재사용이 어려움 (Modal 여러개 일 경우)
  • 모달 하나를 생성하는데 하나의 상태, 작성해야되는 코드들이 많아서 디버깅에 어려움이 있음
const [isShow,setIsShow] = useState(false);
const [isShow1,setIsShow1] = useState(false);
const [isShow2,setIsShow2] = useState(false);

React + Redux (전역 상태를 이용)

interface modalState {
  isOpen:boolean,
  onCloseCallback:Function,
  onActionCallback:Function,
  
}
const Modal = () =>{
  const modal:modalState = useSelector(state => state.modal);
  return modal.isOpen ? <ModalComponent {...modal} /> : null;
}

const App = () => {
  return (
    <Router />
    	<Components...>
     	<Modal />
    </Router>)
}

장점

  • css z-index 등 엘러멘트 구성상 상위에 그려지기에 겹침 현상이 없음
  • 전역 상태를 통해 관리 되기에 모달을 사용하는 곳에선 callback을 통해 이벤트만 전달 받으면 되기에 관리가 편리함

단점

  • 리덕스 기본 원칙인 직렬화 되지 않는 데이터를 넣기에 기본 원칙에 위배됨(함수)
  • 모달을 키는 dispatch가 많아질수록 디버깅에 어려움이 있음

React-CreatePortal + CustomHooks


import { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';

const useModal = ({ Modal }: { Modal: any }) => {
  const ref = useRef<Element | null>();
  const [isShow, setIsShow] = useState(false);

  useEffect(() => {
    const dom = document.getElementById('root-modal');
    ref.current = dom; // ref에 dom 값 전달
  }, []);

  return {
    isShow,
    modalOpen: () => setIsShow(true),
    modalClose: () => setIsShow(false),
    ModalView: () => {
      if (ref.current == null || !isShow) {
        return null;
      }
      return createPortal(<Modal />, ref.current);
    },
  };
};

export default useModal;


const App= () => {
  const {
    isShow,
    modalOpen,
    modalClose,
    ModalView: Portal,
  } = useModal({
    Modal: QRModal, <-- 원하는 모달을 넣어줄 수 있음
  });
  return (
    <Routes>
    	<...Components />
    	<ModalView /> <-- 출력부
    </Routes>
    )
}

createPortal은 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링 하는 방법중 하나 입니다!

장점

  • 커스텀 훅을 통해 상태를 만드는 반복적인 작업이 줄어듬
  • 커스텀 훅에 모달 자체를 전달해주기에 역할이 정확히 구별됌(원하는 모달을 넣어주는 부분에서 callBack 등 props로 전달가능/ 커스텀훅: 모달을 그려주는 역할)
  • 모달을 만드는 부분이 명확해서 디버깅하기 쉬움 + modalOpen이라는 이벤트를 찾으면 되기에 어떻게 열린지 확인또한 쉽게 확인 가능
  • 모달을 여러겹으로 띄울수 있음

단점

  • redux에 비해 모달을 키고 끄는 부분에 있어서 코드량이 상대적으로 많음

End

저는 개인적으로 마지막 방식을 선호해서 프로젝트에 바로 적용 했습니다.
모달을 여러개 띄워야 되는 상황 + 디버깅이 쉬운 상황을 고려해야 되기에 마지막 방식에 맞지 않나 싶습니다.
여러 프로젝트를 하며 모달을 어떻게 하면 효율적으로 관리할까? 이런 고민을 통해 나온 방식들 입니다. 정답은 없지만 그 상황에 맞는 방식은 존재하기에 프로젝트 상황과 모달에 요구사항에 대해 고민해보시고 방법을 고려하시는게 제일 좋은것 같습니다.
위 방식 말고도 좋은 방식이 있으면 언제든 댓글로 알려주세요! 읽어주셔서 감사합니다.

profile
모든건 기록으로

0개의 댓글