JAVASCRIPT
Detecting Clicks Outside a Component with useClickOutside
Create a `useClickOutside` custom React hook to trigger an action when a user clicks outside a specified DOM element, perfect for closing modals or dropdowns.
import React, { useRef, useEffect } from 'react';
// Custom hook for detecting clicks outside a referenced element
function useClickOutside(handler) {
const ref = useRef(null);
useEffect(() => {
const handleClickOutside = (event) => {
// If the ref element exists and the click is outside of it
if (ref.current && !ref.current.contains(event.target)) {
handler(); // Execute the provided handler function
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [handler]); // Re-run if handler changes
return ref;
}
// Component using the useClickOutside hook
function DropdownMenu() {
const [isOpen, setIsOpen] = React.useState(false);
// Use the custom hook, passing a function to close the dropdown
const dropdownRef = useClickOutside(() => setIsOpen(false));
return (
<div style={{ position: 'relative', display: 'inline-block' }}>
<button onClick={() => setIsOpen(!isOpen)}>Toggle Dropdown</button>
{isOpen && (
<div
ref={dropdownRef} // Attach the ref to the dropdown content
style={{
position: 'absolute',
border: '1px solid #ccc',
padding: '10px',
backgroundColor: 'white',
marginTop: '5px',
zIndex: 100
}}
>
<p>Item 1</p>
<p>Item 2</p>
<p>Item 3</p>
</div>
)}
</div>
);
}
export default DropdownMenu;
How it works: The `useClickOutside` custom hook takes a `handler` function. It creates a `useRef` to attach to a DOM element. An `useEffect` hook adds a global `mousedown` event listener. When a click occurs, it checks if the click target is outside the referenced element (`!ref.current.contains(event.target)`). If it is, the provided `handler` function is called (e.g., to close a dropdown or modal). The cleanup function ensures the event listener is removed when the component unmounts.