Back to all snippets
Library/React/useClickOutside Hook
typescriptintermediatehookseventsui

How to implement useClickOutside Hook in Typescript

Detect clicks outside of a component

Quick Answer

useClickOutside attaches mousedown and touchstart listeners to the document and calls a handler whenever the event originates outside the referenced element. It is the standard pattern for closing dropdowns and modals on outside click.

Code Snippet

1import { useEffect, RefObject } from 'react';
2
3function useClickOutside(
4  ref: RefObject<HTMLElement>,
5  handler: (event: MouseEvent | TouchEvent) => void
6) {
7  useEffect(() => {
8    const listener = (event: MouseEvent | TouchEvent) => {
9      if (!ref.current || ref.current.contains(event.target as Node)) {
10        return;
11      }
12      handler(event);
13    };
14
15    document.addEventListener('mousedown', listener);
16    document.addEventListener('touchstart', listener);
17
18    return () => {
19      document.removeEventListener('mousedown', listener);
20      document.removeEventListener('touchstart', listener);
21    };
22  }, [ref, handler]);
23}

What is useClickOutside Hook?

useClickOutside attaches mousedown and touchstart listeners to the document and calls your handler whenever the event target is outside the referenced element. This is the standard pattern for closing dropdowns, modals, pop-overs, and context menus when the user clicks elsewhere on the page.

How It Works

  1. 1A ref is attached to the element you want to detect outside clicks for.
  2. 2A document-level mousedown and touchstart listener fires on every click.
  3. 3If the event target is inside ref.current, the handler is not called.
  4. 4If the event target is outside, the handler fires.
  5. 5The listeners are removed in the useEffect cleanup.

Common Use Cases

  • Dropdown menus - Close the dropdown when user clicks outside
  • Modals - Dismiss modal on backdrop click
  • Tooltips - Hide tooltip when focus moves away
  • Context menus - Close right-click menus on outside click

Key Benefits

  • Handles both mouse and touch events for mobile support
  • Uses ref so it works with any DOM element
  • Cleans up listeners on unmount
  • Zero dependencies beyond React

Common Mistakes to Avoid

  • Wrapping the handler in a new function on every render — memoize it with useCallback to avoid re-registering listeners.
  • Forgetting touch events — mousedown alone misses mobile taps.
  • Using onClick on document instead of mousedown — mousedown fires before the click event, which prevents race conditions with internal click handlers.

Quick Tips

  • Click the "Copy" button above to copy the code to your clipboard
  • This code is production-ready and can be used in your projects immediately
  • Check out related snippets below for more typescript examples

Frequently Asked Questions

Why use mousedown instead of click for outside detection?

mousedown fires before the browser processes the click, so you can close the dropdown before any click handler on the trigger button re-opens it.

Can I use useClickOutside with a portal?

Yes. Portals still propagate events through the React tree, so the contains check on the DOM element works correctly.

Does useClickOutside work for nested dropdowns?

Yes, as long as each nested element has its own ref. The contains method handles any depth of nesting.

About This Typescript Code Snippet

This free typescript code snippet for useclickoutside hook is production-ready and copy-paste friendly. Whether you are building a web app, API, or frontend interface, this intermediate-level example will help you implement useclickoutside hook quickly and correctly.

All snippets in the Snippetly library follow typescript best practices and are tested for real-world use. You can adapt this code to work with React, Vue, Node.js, or any project that uses typescript.

Tags: hooks, events, ui  | Language: typescript  | Difficulty: intermediate  | Category: React

Build Your Own Snippet Library

Organise your team's code snippets with Snippetly. Share knowledge and boost productivity across your organisation.