useRef로 바깥 영역 클릭 시 모달 닫기

blueprint·2022년 11월 10일
2


모달 구현까지는 완료했는데, 바깥 영역을 클릭했을 때 사라지도록 하고 싶어서 방법을 찾다 발견한 솔루션들을 써 볼까 한다. 우선 useRef를 사용하면 쉽게 제어할 수 있다는 사실!

그렇다면 useRef는 언제 쓰는가?
1. 특정 DOM을 선택할 때 (JS의 querySelectorgetElementByID와 같은 역할)
2. 컴포넌트 안에서 조회 및 수정 할 수 있는 변수를 관리

나는 모달 박스를 선택하고 싶기 때문에 우선 useRef를 사용할 수 있는 변수를 만들었다.

const modalRef = useRef();

모달의 상태 관리를 위해 useState도 사용했다. isOpen이 닫혀 있을 때는 false 값을, 열려 있을 때는 true 값을 setIsOpen에다 담아 준다. 클릭하지 않으면 모달이 열리지 않기 때문에 기본값은 false로 주었다.

const [isOpen, setIsOpen] = useState(false);

const handleModal = () => {
	if (isOpen === true) {
		setIsOpen(false);
	} else {
		setIsOpen(true);
    }
};

그런 다음 원하는 컴포넌트에 ref 값으로 위에서 지정한 변수와 onClick 이벤트 함수를 넣어 준다. 이제 MyPageBtn이라는 컴포넌트를 가리키고, onClick 이벤트가 발생했을 때 handleModal이라는 함수를 통해 모달의 상태를 변경해 줄 수 있게 됐다.

<MyPageBtn onClick={handleModal} ref={modalRef} />

DOM 선택까지 끝났으니 바깥 영역을 클릭했는지 감시할 수 있도록 useEffect 안에다 로직을 작성한다. 컴포넌트가 unmount 되는 주기가 많으므로 useEffect 안에서 리턴 문을 통해 click 이벤트를 삭제해 주었다.

useEffect(() => {
	const clickOutside = (e) => {
		if (isOpen && !modalRef.current.contains(e.target)) {
			setIsOpen(false);
		}
	};
  
	document.addEventListener("mousedown", clickOutside);
	
  return () => {
		document.removeEventListener("mousedown", clickOutside);
	};
}, [isOpen]);

🔗 참고
useRef 로 특정 DOM 선택하기

0개의 댓글