Published on

🪝️ Detecting Outside Clicks with useOutsideClick Hook

This custom hook takes a ref of the target element and a callback function that will be executed when a click outside that element is detected.

Custom Hook: useOutsideClick.ts

import { useEffect } from 'react';

function useOutsideClick(ref: React.RefObject<HTMLElement>, callback: () => void): void {
  useEffect(() => {
    // Function to handle clicks
    const handleClickOutside = (event: MouseEvent): void => {
      // Check if the click target is outside the ref element
      if (ref.current && !ref.current.contains(event.target as Node)) {
        callback();
      }
    };

    // Bind the event listener
    document.addEventListener('mousedown', handleClickOutside);

    // Clean up the event listener on component unmount
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [ref, callback]); // Re-run if ref or callback changes
}

export default useOutsideClick;

How to Use the Custom Hook in a Component

import React, { useRef, useState } from 'react';
import useOutsideClick from './useOutsideClick'; // Adjust the path as necessary

const ExampleComponent: React.FC = () => {
  const [isOpen, setIsOpen] = useState<boolean>(false);
  const ref = useRef<HTMLDivElement>(null); // Ref for the dropdown

  // Callback function to handle the outside click
  const handleOutsideClick = (): void => {
    setIsOpen(false);
  };

  // Use the custom hook
  useOutsideClick(ref, handleOutsideClick);

  return (
    <div>
      <button onClick={() => setIsOpen(prev => !prev)}>
        Toggle Dropdown
      </button>
      {isOpen && (
        <div ref={ref} style={{ border: '1px solid black', padding: '10px' }}>
          <p>This is a dropdown. Click outside to close it.</p>
        </div>
      )}
    </div>
  );
};

export default ExampleComponent;