Skip to content

Instantly share code, notes, and snippets.

@theoperatore
Created January 28, 2019 14:02
Show Gist options
  • Save theoperatore/e640077a5a2f235c26bb6b4097981c33 to your computer and use it in GitHub Desktop.
Save theoperatore/e640077a5a2f235c26bb6b4097981c33 to your computer and use it in GitHub Desktop.
two custom hooks; 1 for appending a DOM node to the document for use in a Portal. Another for conditionally adding an event listener to handle outside of flyout menu clicks (so it can close)
const useDOMDiv = (changeToUpdate: number = 1) => {
const nodeRef = React.useRef(document.createElement('div'));
React.useEffect(() => {
document.body.appendChild(nodeRef.current);
return () => document.body.removeChild(nodeRef.current);
}, [changeToUpdate]);
return nodeRef.current;
};
const useOutsideClick = (
node: HTMLDivElement,
isOpen: boolean,
onOutsideClick: () => void,
) => {
React.useEffect(() => {
const handleOutsideClick = (ev: MouseEvent) => {
if (!node.contains(ev.target as Element)) {
onOutsideClick();
}
};
if (isOpen) {
document.addEventListener('click', handleOutsideClick);
}
return () => document.removeEventListener('click', handleOutsideClick);
}, [isOpen]);
};
@theoperatore
Copy link
Author

you'd use them like this:

const [isOpen, setMenuState] = useState(false);
const close = () => setMenuState(false);

const node = useDOMDiv();
useOutsideClick(node, isOpen, close);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment