프론트엔드/React
리액트 모달 외부 클릭시 창 닫기
카엔입니다
2022. 9. 27. 14:57
해당 코드
const [isToggle, setIsToggle] = useState(false);
const modalRef = useRef<any>();
const closeModalHandler = (e) => {
if (isToggle && (!modalRef.current || !modalRef.current.contains(e.target))) setIsToggle(false);
};
useEffect(() => {
window.addEventListener("click", closeModalHandler);
return () => {
window.removeEventListener("click", closeModalHandler);
};
}, []);
return (
<Modal ref={modalRef}>
...
</Modal>
)
모달에 해당하는 DOM을 ref로 지정
클릭 이벤트가 발생하면 모달에 current 상태와 현재 이벤트를 실행한 element가 e.target에 포함되어있는지 확인
useCustomHook
해당 코드를 재사용하기 위해 커스텀 훅으로 만들 수 있다
Custom Hook
import { useEffect, useRef } from 'react'
export default function useOnClickOutsideRef(callback, initialState = null) {
const thisDomRef = useRef(initialState);
useEffect(() => {
function modalCloseHandler(event) {
if (!thisDomRef.current?.contains(event.target)) {
callback()
}
}
window.addEventListener('click', modalCloseHandler);
return () => window.removeEventListener('click', modalCloseHandler);
}, [callback]);
return thisDomRef;
}
코드 적용
const App = () => {
const [isOpen, setIsOpen] = useState(true)
const modalRef = useOnClickOutsideRef(() => setIsOpen(false))
return (
<div>
<button onClick={() => setIsOpen(true)}>Open Modal</button>
<Modal ref={modalRef} isOpen={isOpen}>
...
</Modal>
</div>
)
}