Skip to content

How to close a menu when clicking outside

This example demonstrates how to close a menu when clicking outside using the useOutsideClick hook.

Watch the live preview.

tsx
import { useState, useRef } from "react";
import { useOutsideClick } from "./useOutsideClick";

export default function App() {
  const [isOpen, setIsOpen] = useState(false);
  const dropdownRef = useRef<HTMLDivElement>(null);

  const toggleMenu = () => {
    setIsOpen(!isOpen);
  };

  const closeMenu = () => {
    setIsOpen(false);
  };

  useOutsideClick(dropdownRef, closeMenu);

  return (
    <div ref={dropdownRef}>
      <button onClick={toggleMenu}>Show menu</button>
      {isOpen && (
        <div>
          <ul>
            <li>Profile</li>
            <li>Settings</li>
            <li>Logout</li>
          </ul>
        </div>
      )}
    </div>
  );
}
typescript
import { useEffect, RefObject } from "react";

export const useOutsideClick = (
  ref: RefObject<HTMLElement | null>,
  fn: () => void
) => {
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (ref.current && !ref.current.contains(event.target as Node)) {
        fn();
      }
    };

    document.addEventListener("click", handleClickOutside);

    return () => {
      document.removeEventListener("click", handleClickOutside);
    };
  }, [ref, fn]);
};