When we implement a dropdown or drawer component in React, these components often require to be closed when mouse-clicking either the menu button or outside of the component.
To allow this behavior in our custom components, we can create a custom hook that allows us to apply the same behavior whenever we need it.
Here is a simple custom hook that checks if the mouse clicks outside of the current component.
const useCheckOutside =
(clickOutside: () => void, exceptId?: string) => ...
We named the hook useCheckOutside
, and it receives the clickOutside
function as a property that allows the parent component to receive the event.
exceptId
is an optional property that can be used to ignore the place where we don't want the close behavior when the place is clicked. We need this because usually the menu or the dropdown button is also a part of the outside clicks, and the button's onClick
event changes the menu or dropdown's visibility to be visible whereas the outside click changes the visibility to be hidden. The below function describes that the exceptId
will be ignored in the mousedown
event.
const checkOutsideClick = (event: any) => {
if (
ref.current &&
!ref.current.contains(event.target) &&
event.target.id !== exceptId
) {
clickOutside();
}
};
document.addEventListener('mousedown', checkOutsideClick);
Here is the entire code for the useCheckoutside
hook with a simple example of how to use.
import { useEffect, useRef } from 'react';
const useCheckOutside =
(clickOutside: () => void,
exceptId?: string) => {
const ref = useRef<any>();
useEffect(() => {
const checkOutsideClick = (event: any) => {
if (
ref.current &&
!ref.current.contains(event.target) &&
event.target.id !== exceptId
) {
clickOutside();
}
};
document.addEventListener('mousedown', checkOutsideClick);
return () => {
document.removeEventListener('mousedown', checkOutsideClick);
};
}, [clickOutside]);
return ref;
};
export default useCheckOutside;
const handleOutsideClick = () => {
setOpen(false);
}
const ref = useCheckOutside(handleOutsideClick, "buttonId");
return <>
<button id="buttonId" type="button"
onClick={(e) => {
setOpen(true)
}
>
Menu
</button>
{open && <Menu ref={ref} />}
</>
Top comments (0)