← Back to all snippets
JAVASCRIPT

Custom `useClickOutside` Hook for Closing Modals/Dropdowns

Implement a React `useClickOutside` hook to detect clicks outside a specified DOM element, perfect for automatically closing dropdowns, modals, or context menus.

import { useEffect, useRef } from 'react';

function useClickOutside(handler) {
  const domNodeRef = useRef();

  useEffect(() => {
    const maybeHandler = (event) => {
      // If the clicked target is not within the ref's current element
      if (domNodeRef.current && !domNodeRef.current.contains(event.target)) {
        handler(); // Execute the provided handler function
      }
    };

    document.addEventListener('mousedown', maybeHandler);

    return () => {
      document.removeEventListener('mousedown', maybeHandler);
    };
  }, [handler]); // Re-run effect if handler changes

  return domNodeRef;
}

// Example Usage:
// function Dropdown() {
//   const [isOpen, setIsOpen] = useState(false);
//   const dropdownRef = useClickOutside(() => setIsOpen(false));

//   return (
//     <div ref={dropdownRef} style={{ border: '1px solid black', padding: '10px' }}>
//       <button onClick={() => setIsOpen(!isOpen)}>Toggle Dropdown</button>
//       {isOpen && (
//         <ul style={{ background: '#f0f0f0', marginTop: '5px', listStyle: 'none', padding: '10px' }}>
//           <li>Item 1</li>
//           <li>Item 2</li>
//         </ul>
//       )}
//     </div>
//   );
// }
How it works: The `useClickOutside` hook takes a `handler` function as an argument and returns a `ref`. When a component mounts, it adds a `mousedown` event listener to the `document`. This listener checks if the clicked target is outside the element referenced by `domNodeRef`. If it is, the provided `handler` function is executed, typically to close a modal or dropdown. The `useEffect` cleanup function ensures the event listener is removed when the component unmounts, preventing memory leaks.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs