Last active
September 20, 2022 09:49
-
-
Save anthowen/e2a50f506bd6fb29f16bc898286ecac5 to your computer and use it in GitHub Desktop.
useOutsideClick (TypeScript) - a custom react hook that handles outside click event of certain area. It also ignores click event on browser's scrollbar.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect, RefObject } from 'react'; | |
/** | |
* Hook that handles outside click event of the passed refs | |
* | |
* @param refs array of refs | |
* @param handler a handler function to be called when clicked outside | |
*/ | |
export default function useOutsideClick( | |
refs: Array<RefObject<HTMLElement> | undefined>, | |
handler?: () => void, | |
) { | |
useEffect(() => { | |
function handleClickOutside(event: any) { | |
if (!handler) return; | |
// Clicked browser's scrollbar | |
if ( | |
event.target === document.getElementsByTagName('html')[0] && | |
event.clientX >= document.documentElement.offsetWidth | |
) | |
return; | |
let containedToAnyRefs = false; | |
for (const rf of refs) { | |
if (rf && rf.current && rf.current.contains(event.target)) { | |
containedToAnyRefs = true; | |
break; | |
} | |
} | |
// Not contained to any given refs | |
if (!containedToAnyRefs) { | |
handler(); | |
} | |
} | |
// Bind the event listener | |
document.addEventListener('mousedown', handleClickOutside); | |
return () => { | |
// Unbind the event listener on clean up | |
document.removeEventListener('mousedown', handleClickOutside); | |
}; | |
}, [refs, handler]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Different onOutsideClick hooks I've tried so far caused the problem that too many clicks were registered and inside clicks as well.
Because I have multiple instances of the component that should listen to outside clicks.
So I'm happy I found your hook. Now instead of using the hook inside of the
But I wasn't sure how to assign the refs.
I tried this:
and this is how the refs are assigned:
The type definition inside your hook I changed to:
This is just me experimenting. I of course tried it with RefObject as well.
But I don't know what I'm doing, really. Refs are very confusing when it comes to Typescript.
My problem is that I get:
and
Maybe you know what to do?