← Back to all snippets
JAVASCRIPT

Detecting Clicks Outside an Element with useClickOutside Hook

Implement a custom React `useClickOutside` hook to trigger a callback when a user clicks outside a specified DOM element, perfect for dropdowns and modals.

import { useEffect } from 'react';

function useClickOutside(ref, handler) {
  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]); // Re-run if ref or handler changes
}

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

  return (
    <div ref={dropdownRef}>
      <button onClick={() => setIsOpen(!isOpen)}>Toggle Dropdown</button>
      {isOpen && (
        <div style={{ border: '1px solid black', padding: '10px' }}>
          Dropdown Content
        </div>
      )}
    </div>
  );
}
*/
How it works: The `useClickOutside` hook takes a `ref` to the element to monitor and a `handler` function. It attaches `mousedown` and `touchstart` event listeners to the `document`. When an event occurs, it checks if the click happened *inside* the referenced element. If not, the provided `handler` function is called. The `useEffect` cleanup function ensures that the event listeners are properly removed when the component unmounts or dependencies change, 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