← Back to all snippets
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.

Need help integrating this into your project?

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

Hire DigitalCodeLabs