В приведённом ниже примере сначала выполняется обработчик нажатия на кнопку (click в консоли), а затем уже обработчик клика вне элемента (outside в консоли). Можно ли как-то это исправить, чтобы outside всегда выполнялся до click?
import {FC, RefObject, useEffect, useRef, useState} from "react";
function useEventListener(event: string, callback: (e: any) => void, element: EventTarget = document) {
const callbackRef = useRef(callback)
useEffect(() => {
callbackRef.current = callback
}, [callback])
useEffect(() => {
const handler = (e:any) => callbackRef.current(e)
element.addEventListener(event, handler)
return () => {
element.removeEventListener(event, handler)
};
}, [event, element])
}
export function useClickOutside(ref:RefObject<HTMLDivElement>,cb:(param:any)=>any){
useEventListener(
"click",
e => {
if (ref.current == null || ref.current.contains(e.target)) return
cb(e)
},
document
)
}
const UseClickOutsideExample:FC = ()=>{
const [open, setOpen] = useState(false)
const modalRef = useRef<HTMLDivElement>(null)
useClickOutside(modalRef, () => {
console.log('outside')
if (open) setOpen(prev=>prev?false:prev)
})
return (
<>
<button onClick={() => {console.log('click');setOpen(true)}}>Open</button>
<div
ref={modalRef}
style={{
display: open ? "block" : "none",
backgroundColor: "blue",
color: "white",
width: "100px",
height: "100px",
position: "absolute",
top: "calc(50% - 50px)",
left: "calc(50% - 50px)",
}}
>
<span>Modal</span>
</div>
</>
)
}
export default UseClickOutsideExample;