해당 코드
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>
)
}
'프론트엔드 > React' 카테고리의 다른 글
react lightweight chart 트레이딩뷰 마우스 이탈 이벤트 (0) | 2022.10.23 |
---|---|
리덕스 dispatch시 렌더링 발생 방식 및 최적화 (0) | 2022.09.28 |
React DatePicker click on close (1) | 2022.09.26 |
useEffect (0) | 2022.06.13 |
React 리액트 렌더링 과정 (0) | 2022.06.11 |