useClickOutside
Detect clicks outside a specific element to trigger a callback function.
useClickOutside
Detect clicks outside a specific element to trigger callbacks like closing modals or dropdowns.
Installation
npx open-hook add useClickOutsideyarn dlx open-hook add useClickOutsidepnpm dlx open-hook add useClickOutsideAPI Reference
Parameters
| Prop | Type | Default |
|---|---|---|
callback? | () => void | - |
ref? | React.RefObject<HTMLElement> | - |
Returns
No Return Value
This hook performs a side effect and does not return any value.
TypeScript Signature
function useClickOutside(
ref: React.RefObject<HTMLElement>,
callback: () => void
): void;Best Practices
Use useCallback for the callback function to prevent unnecessary re-renders:
const handleClose = useCallback(() => {
setIsOpen(false);
}, []);
useClickOutside(modalRef, handleClose);Do's and Don'ts
- ✅ Use
useCallbackfor static callbacks - ✅ Ensure the ref is properly attached to the target element
- ✅ Consider using
useReffor better performance - ❌ Avoid using this hook with frequently changing callbacks without memoization
- ❌ Don't forget to handle cases where the ref might be null
Performance Metrics
| Metric | Value | Description |
|---|---|---|
| Bundle Size | ~0.8kb | Minified + gzipped |
| Re-renders | None | Only side effect, no state |
| Memory | Minimal | Single event listener |
| First Paint | +0ms | No blocking operations |
Browser Compatibility
| Browser | Supported | Notes |
|---|---|---|
| Chrome (latest) | ✅Yes | Full support |
| Firefox (latest) | ✅Yes | Full support |
| Safari (latest) | ✅Yes | Full support |
| Edge (latest) | ✅Yes | Full support |
| IE 11 | ❌No | Not supported |
| Node.js | ✅Yes | For SSR environments |
Use Cases
Modal Dialogs
Perfect for closing modals when users click outside the modal area.
Dropdown Menus
Close dropdown menus when clicking elsewhere on the page.
Search Suggestions
Hide search suggestion panels when clicking outside the search box.
Mobile Sidebars
Collapse navigation sidebars on mobile when tapping outside.
Accessibility
Accessibility Considerations
- The hook respects keyboard navigation and only handles mouse events -
Consider adding
Escapekey support for better accessibility - Ensure focus management is handled separately for screen readers
Troubleshooting
Internals
How It Works
The hook uses a single mousedown event listener on the document to detect clicks. When a click occurs, it checks if the clicked element is contained within the referenced element using Node.contains(). If the click is outside, it triggers the provided callback.
The event listener is automatically cleaned up when the component unmounts or dependencies change.
Testing Example
import { renderHook } from "@testing-library/react";
import { useRef } from "react";
import { useClickOutside } from "./useClickOutside";
it("calls callback when clicking outside element", () => {
const callback = jest.fn();
const ref = { current: document.createElement("div") };
renderHook(() => useClickOutside(ref, callback));
// Simulate click outside
const outsideElement = document.createElement("div");
document.body.appendChild(outsideElement);
const event = new MouseEvent("mousedown", { bubbles: true });
outsideElement.dispatchEvent(event);
expect(callback).toHaveBeenCalledTimes(1);
});FAQ
Related Hooks
- useKeyPress - Handle keyboard events
- useEventListener - Generic event listener hook
- useOnClickOutside - Alternative implementation
Changelog
- 1.1.0 — Added better TypeScript support and performance optimizations
- 1.0.0 — Initial release with basic click outside detection