React | 외부 영역 클릭 이벤트 감지

yes·2022년 10월 3일
1

React

목록 보기
5/8

문제 상황 🧐

다음 이미지와 같이 드랍다운과 모달 외부 영역을 클릭할 때 드랍다운을 닫거나 모달을 닫는 기능을 구현해야 했다.
하지만 해당하는 컴포넌트의 이벤트는 감지하는 법을 알았지만, 해당 컴포넌트 외부 영역에 이벤트를 감지하여 원하는 기능을 구현하는 법은 알지 못했다.


구현 방법 ✨

  1. window에 event를 listen한다.
  2. 외부 영역과 해당 영역을 구분할 수 있는 기준을 잡는다.

코드 🎯

모달 외부 영역 클릭 시 모달이 닫힘

const Modal = ({ closeModal, isOpenModal }: IModalProps) => {
  const modalRef = useRef<HTMLDivElement>(null);
  useEffect(() => {
    const handleClick = (e: MouseEvent) => {
      if (modalRef.current && !modalRef.current.contains(e.target as Node)) {
        closeModal();
      }
    };
    window.addEventListener('mousedown', handleClick);
    return () => window.removeEventListener('mousedown', handleClick);
  }, [modalRef]);

  return (
    <Overlay>
      <ModalWrap ref={modalRef}>
        <ModalCloseBtn onClick={closeModal} style={{ cursor: 'pointer' }}>
          <Image src="/images/close_Btn.png" width={40} height={40} />
        </ModalCloseBtn>
      </ModalWrap>
    </Overlay>
  );
};
  • modal의 열림과 닫힘의 상태는 아래와 같이 useState로 관리했다.
    const [isOpenModal, setIsOpenModal] = useState(false)

    modal의 외부 영역 클릭 시인데 click이 아니라 mousedown 이벤트인 이유

  • 현재 나의 코드는 modal을 open할 때 click이벤트를 통해서 isOpenModal을 true값으로 바꾼다.

  • window도 click이벤트를 감지하게 되면 modal을 open하는 이벤트를 listen할 때 이벤트 버블링으로 인해 window 또한 click 이벤트를 listen하게 되어 modal이 열리자마자 닫히기 때문에 click이벤트가 아닌 mousedown이벤트를 사용해야 한다.

  • !modalRef.current.contains(e.target as Node)
    modalRef는 외부 영역과 해당 모달 영역을 구분 짓는 구분 점인 Ref 객체이다.
    우리는 이 외부 영역이라는 조건이 있기 때문에 해당 조건을 추가한 것이다.
    외부 영역을 클릭 시에는 해당 조건이 true로 나오게 된다.

참고 자료 📖

https://sezzled.tistory.com/147
https://velog.io/@miyoni/TIL37
감사합니다

0개의 댓글