모달 외의 다른 곳을 클릭할 경우 모달의 창을 닫게 하는 Hooks를 만들어보자
먼저 모달창과 그 외의 부분을 구별해주어야 하는데
모달창에 해당하는 태그에 ref={ref}로 지정해주어 구분해준다
import React, { useRef } from "react";
const ref=useRef(null)
useOnClickOutside(ref,()=>{
setModalOpen(false)
})
<div className="modal" ref={ref}>
.
.
.
</div>
ref의 초기값을 null로 지정해주고 useOnClickOutside에 ref와 handler를 넣어준다
import { useEffect } from "react"
export const useOnClickOutside=(ref,handler)=>{
useEffect(()=>{
const listener=(event)=>{
// console.log('이벤트타켓',event.target)
if( ref.current===null || ref.current.contains(event.target)){
return
}
handler()
}
document.addEventListener('mousedown',listener)
document.addEventListener('touchstart',listener)
return ()=>{
document.removeEventListener('mousedown',listener)
document.removeEventListener('touchstart',listener)
}
},[ref,handler])
}
useEffect를 통해 ref,handler가 변할 때마다 랜더링 하게 만들고 addEventListener를 이용해 listener 함수를 실행시킨다.
listener함수의 event.target은 모달의 범위, 즉 ref의 범위가 지정되어있으므로 if문을 통해 해당 범위 외의 mousedown,touchstart을 할 경우 만들어놓은 handler를 실행시키도록 설정한다