TIL37 | React | ref를 이용한 outside click 외부 클릭 감지
리액트의 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