useClickOutside
A React hook that detects clicks outside of a specified element. Perfect for implementing dismissible UI components like modals, dropdowns, and popups. Supports both mouse and touch events with TypeScript type safety.
Live Demo
Times clicked outside: 0
Implementation
type Handler = (event: MouseEvent | TouchEvent) => void;
export function useClickOutside<T extends HTMLElement>(
ref: RefObject<T | null>,
handler: Handler,
mouseEvent: "mousedown" | "mouseup" = "mousedown"
): void {
useEffect(() => {
const listener = (event: MouseEvent | TouchEvent) => {
const el = ref?.current;
if (!el || el.contains((event?.target as Node) || null)) {
return;
}
handler(event);
};
document.addEventListener(mouseEvent, listener);
document.addEventListener("touchstart", listener);
return () => {
document.removeEventListener(mouseEvent, listener);
document.removeEventListener("touchstart", listener);
};
}, [ref, handler, mouseEvent]);
}
Usage
import { useRef } from 'react';
import { useClickOutside } from '@/components/hooks/useClickOutside';
function MyComponent() {
const ref = useRef(null);
useClickOutside(ref, () => {
console.log('Clicked outside!');
// Handle click outside (e.g., close modal, hide dropdown)
});
return (
<div ref={ref}>
Click outside this element!
</div>
);
}
Important Notes
Event Types
The hook supports both mouse and touch events, making it work across different devices and input methods:
- Mouse events (configurable between mousedown and mouseup)
- Touch events (touchstart)
- Proper cleanup of event listeners on unmount
Use Cases
- Modal dialogs
- Dropdown menus
- Popover components
- Context menus