I have a react hook that detects a click outside the element:
export const useClickOutside = (
ref: React.MutableRefObject<HTMLDivElement | null>,
callback: Function,
) => {
const handleClick = (e: MouseEvent) => {
if (ref.current && !ref.current.contains(e.target as Node) {
callback();
}
};
useEffect(() => {
document.addEventListener('click', handleClick, true);
return () => {
document.removeEventListener('click', handleClick, true);
};
}, [ref, callback]);
};
I use it to close Dropdown elements. I thought that this event would be triggered in any situation, with any click anywhere in the document.
But in my application there are schemes that are based on mxGraph. They are built inside svg. And when clicking on the labels of some objects, the document click handler does not work.
For what reasons can this handler fail?
2
Answers
The problem is you have added useEffect inside the function put it seperate outside the function here is the updated code.
To prevent the dependencies of the
useEffect
hook changing on every render, you should move thehandleClick
function inside theuseEffect
hook. Alternatively, wrap the definition ofhandleClick
in its ownuseCallback
hook.Here’s a final implementation that takes this into account:
Or using the
useCallback
hook:As a side note your syntax is also incorrect. You are missing a closing bracket in the
ref.current && !ref.current.contains(e.target as Node)
expression. It should have been: