모달 구현까지는 완료했는데, 바깥 영역을 클릭했을 때 사라지도록 하고 싶어서 방법을 찾다 발견한 솔루션들을 써 볼까 한다. 우선 useRef
를 사용하면 쉽게 제어할 수 있다는 사실!
그렇다면 useRef는 언제 쓰는가?
1. 특정 DOM을 선택할 때 (JS의 querySelector
나 getElementByID
와 같은 역할)
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 선택하기