DevFiddleDevFiddle
HomeToolsSnippetsArticles
Explore tools
Home>Snippets>useClickOutside React Hook
React
#Hooks#DOM#Modals

useClickOutside React Hook

Detect clicks outside a designated element to dismiss dropdowns, modals, and popovers smoothly.

October 10, 20262 min read

Dismissing context menus, dropdown pickers, and modals when a user clicks outside the element is a staple pattern in UI development.

The Hook Implementation

import { useEffect, type RefObject } from "react";
 
export function useClickOutside<T extends HTMLElement = HTMLElement>(
  ref: RefObject<T | null>,
  handler: (event: MouseEvent | TouchEvent) => void
): void {
  useEffect(() => {
    const listener = (event: MouseEvent | TouchEvent) => {
      const el = ref?.current;
      // Do nothing if clicking target element or descendent elements
      if (!el || el.contains((event.target as Node) || null)) {
        return;
      }
 
      handler(event);
    };
 
    document.addEventListener("mousedown", listener);
    document.addEventListener("touchstart", listener);
 
    return () => {
      document.removeEventListener("mousedown", listener);
      document.removeEventListener("touchstart", listener);
    };
  }, [ref, handler]);
}

Example Usage

import { useState, useRef } from "react";
import { useClickOutside } from "./useClickOutside";
 
export function DropdownMenu() {
  const [isOpen, setIsOpen] = useState(false);
  const menuRef = useRef<HTMLDivElement>(null);
 
  // Close menu when clicking outside
  useClickOutside(menuRef, () => setIsOpen(false));
 
  return (
    <div ref={menuRef} className="relative inline-block">
      <button onClick={() => setIsOpen((prev) => !prev)}>
        Toggle Options
      </button>
 
      {isOpen && (
        <div className="absolute right-0 mt-2 w-48 bg-white shadow-lg rounded-md p-2">
          <p className="p-2 hover:bg-gray-100 cursor-pointer">Profile</p>
          <p className="p-2 hover:bg-gray-100 cursor-pointer">Settings</p>
          <p className="p-2 hover:bg-gray-100 cursor-pointer text-red-500">Log out</p>
        </div>
      )}
    </div>
  );
}

Related snippets

Explore more utility functions, patterns, and code snippets.

View all snippets
React
useLocalStorage Custom React Hook

A robust React hook for syncing component state with window.localStorage across tabs.

#React#Hooks#LocalStorage
View snippet
TypeScript
Debounce Function with TypeScript

A type-safe debounce implementation that delays executing a function until a specified wait time has elapsed.

#TypeScript#Utilities#Performance
View snippet
CSS
Fluid Typography with CSS Clamp

Scale font sizes smoothly across mobile and desktop screens without media query breakpoints.

#CSS#Responsive#Typography
View snippet
About© DevFiddle 2026