JAVASCRIPT
useClickOutside to detect clicks outside an element
A powerful React hook to detect clicks occurring outside a specific DOM element, useful for closing dropdowns, modals, or context menus.
import { useEffect, useRef } from 'react';
function useClickOutside(handler) {
const ref = useRef();
useEffect(() => {
const listener = (event) => {
// Do nothing if clicking ref's element or descendant elements
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]); // Only re-run if ref or handler changes
return ref;
}
// Example Usage:
// function DropdownMenu() {
// const [isOpen, setIsOpen] = useState(false);
// const dropdownRef = useClickOutside(() => setIsOpen(false));
// return (
// <div ref={dropdownRef} style={{ position: 'relative' }}>
// <button onClick={() => setIsOpen(!isOpen)}>Toggle Dropdown</button>
// {isOpen && (
// <div style={{ border: '1px solid black', padding: '10px', position: 'absolute' }}>
// <p>Item 1</p>
// <p>Item 2</p>
// </div>
// )}
// </div>
// );
// }
How it works: The `useClickOutside` hook detects clicks outside a referenced DOM element. It takes a `handler` function that will be executed when an outside click occurs. The hook returns a `ref` that should be attached to the element you want to monitor. Internally, it uses `useEffect` to attach global `mousedown` and `touchstart` event listeners. It checks if the click target is within the referenced element, and if not, it calls the provided handler. This is essential for UI components like dropdowns, tooltips, and modals that need to close when the user clicks elsewhere.