useOnClickOutside
export const useOnClickOutside = (ref, handler) => {
React.useEffect(() => {
const listener = (event) => {
if (!ref.current || ref.current.contains(event.target)) {
return;
}
handler(event);
};
document.addEventListener('mousedown', listener);
document.addEventListener('touchstart', listener);
return () => {
document.removeEventListener('mousedown', listener);
document.removeEventListener('touchstart', listener);
};
}, [ref, handler]);
};
Why?
This hook allows you to detect clicks outside of a specified element.
The idea with moving this logic into a hook is so that we can easily use it across all of our components that need this kind of functionality (dropdown menus, tooltips, etc).
Usage
import React from 'react';
function App() {
// Create a ref that we add to the element for which we want to detect outside clicks
const ref = React.useRef();
// State for our modal
const [isModalOpen, setModalOpen] = React.useState(false);
// Call hook passing in the ref and a function to call on outside click
useOnClickOutside(ref, () => setModalOpen(false));
return (
<>
{isModalOpen ? (
<div ref={ref}>
👋 Hey, I'm a modal. Click anywhere outside of me to close.
</div>
) : (
<button onClick={() => setModalOpen(true)}>Open Modal</button>
)}
</>
);
}