useffect return, outside클릭시 모달 닫기

j_wisdom_h·2024년 3월 18일
0

React

목록 보기
2/4

useffect return, outside클릭시 모달 닫기

useEffect의 return 정리 함수

TIL37 | React | ref를 이용한 outside click 외부 클릭 감지

useEffect 정리함수

리액트의 useEffect는 return () => 으로 표현되는 정리 함수를 가지고 있다. return은 실행을 대기하고 있다가 이전의 효과를 '정리'해주는 함수인 것이다.

 useEffect(() => {
    if (isMenuOpen) {
      // 메뉴의 스크롤 부분 처리
      document.body.classList.add('overflow-hidden');

      return () => {
        document.body.classList.remove('overflow-hidden');
      };
    }
  }, [isMenuOpen]);

isMenuOpen이 true가 되면 classList.add 줄이 실행되고, return 정리 함수는 (if문 안에 있음에도 불구하고) 실행되지 않는다. 다음 isMenuOpen이 변경될 때를 대비하여 미리 '실행이 예약'된다.

이후 dependency 배열에 있던 isMenuOpen이 변경되면(false),

'예약'되어 있던 return 정리 함수가 실행되어 classList.remove 라인이 작동한다.

나중에 또 다시 isMenuOpen이 true가 되면 if문의 첫 번째 줄이 실행되고, isMenuOpen이 false로 다시 변경되면 '예약'되어 있던 return 함수가 실행되는 과정이 반복된다.

⭐ if-else 문으로 처리하는 코드보다 useEffect라는 훅이 가진 특성을 십분 활용한다.

    const handleModalClick = useCallback(
        (e: MouseEvent) => {
            const outside =
                isOpenModal &&
                modalRef.current &&
                !modalRef.current.contains(e.target as Node)
            if (outside) setIsModalOpen(false)
        },
        [isOpenModal, modalRef],
    )
    useEffect(() => {
        window.addEventListener('mousedown', handleModalClick)
        return () => window.removeEventListener('mousedown', handleModalClick)
    }, [handleModalClick])

초기값 isOpenModal = false

  1. 검색창이 클릭되어 모달이 열린다. (isOpenModal = true)
  2. useCallback의 의존성(isOpenModal)이 변했으므로 handleModalClick함수가 재생성된다. 그 결과 useEffect가 실행되고 moudedown에 이벤트가 등록된다.
  3. return () ⇒… 정리함수를 예약한다.(실행x)
  4. 클릭하게 되면 이벤트리스너에의해 handleModalClick함수가 실행되는데 모달 바깥을 클릭하게 되면 isOpenModal =false가 된다.
  5. 그에따라 handleModalClick 이 재생성된다.
  6. handleModalClick 이 재생성되면서 useEffect가 실행되는데, 이때 return 정리함수를 실행한다. 그 결과 mousedown이벤트가 해제된다.
  7. 반복…
profile
뚜잇뚜잇 FE개발자

0개의 댓글