Custom hook — useClickOutside()

Abhishek Gangwar
2 min readApr 4, 2024

A Hook that detects if the user has clicked outside the container.

Photo by Lautaro Andreani on Unsplash

Introduction

Hey there, tech enthusiasts! Today, we’re diving into the fascinating world of React hooks again. This time with a quirky little Hook called useClickOutside().

If you've ever wondered how to tell when a user clicks outside a specific component, buckle up, because we're about to embark on a hilarious journey through the land of event listeners and state management to create a custom hook.

The Problem: Dealing with Clicks Outside Your Components

Picture this scenario: you’ve painstakingly crafted a beautiful dropdown menu for your web application. It’s elegant, it’s functional, but there’s just one problem — it refuses to close when the user clicks outside of it. Frustrating isn’t it? This is a common challenge many developers face when dealing with user interactions in web applications.

The Implementation — useClickOutside() Hook

import React, { useEffect } from "react";

/**
* useClickOutside Hook
* @param {*} callback
* @returns ref which needs to be added on component, outside which we need to listen for Clicks
*/
export default function useClickOutside(callback) {
const ref = React.useRef(null);
const rootElement = document.getElementById("root");

// Registers the Click Event
function registerClickEventListener() {
rootElement.addEventListener("click", (event) => {
if (ref.current && !ref.current.contains(event.target)) {
callback();
}
});
}

// un-registers the Click Event
function unRegisterClickEventListener() {
rootElement.addEventListener("click", (event) => {
if (event.target === ref.current) {
callback();
}
});
}

useEffect(() => {
registerClickEventListener();

return () => {
unRegisterClickEventListener();
};
}, []);

return ref;
}

How to use useClickOutside Inside React component?


function HomePage() {
// ref that needs to be attached to the component outside which we are listening for clicks
const dropDownRef = useClickOutside(onOutsideClick);

const onOutsideClick = () => {
// Do something when outside click is detected
};

return <DropDown ref={dropDownRef}>
// Render Childrens
</DropDown>
}

Explanation

  1. useClickOutside hook accepts a callback and returns a reference.
  2. You can pass in a function as a callback that gets triggered whenever a click is detected outside the component.
  3. It creates a reference (ref) to the component we're monitoring for clicks outside.
  4. Sets up an event listener on the root element of the document to capture click events.
  5. When a click occurs, it checks if the clicked element matches the monitored component. If it’s outside, it triggers the provided callback.
  6. Removes the event listener when the component unmounts to prevent memory leaks.

--

--