DEV Community

Cover image for 4 Ways To Make React Outside Click Handler
Hasanul Haque Banna
Hasanul Haque Banna

Posted on

4 Ways To Make React Outside Click Handler

Greetings, fellow developers! Welcome to the fascinating world of React.js, the renowned JavaScript library created by Facebook that has taken the development community by storm. Within the captivating realm of React.js, a wide array of projects prominently feature modal dialogs, stylish sidebars, and various user interface components.

However, one common challenge developers often face is detecting clicks outside these engaging components. Picture a scenario where a modal should elegantly disappear or a sidebar should smoothly retract when a user clicks outside their designated areas.

The great news is that React provides a wealth of innovative techniques to master the art of managing "React outside click" scenarios, enabling us to craft enchanting user experiences. In this article, I will present four distinct approaches to gracefully handle outside clicks in your React applications, each offering its own unique charm and elegance.

1. Pure React Approach

You can achieve this with a pure React implementation by using a combination of the useEffect and useRef hooks. Here's an example:

import React, { useRef, useEffect, useState } from "react";
const OutsideClick: React.FC<{ children: React.ReactNode }> = ({
  children,
}) => {
  const ref = useRef<HTMLDivElement | null>(null);
  const [isOpen, setIsOpen] = useState(false);

  const handleClickOutside = (event: MouseEvent) => {
    if (ref.current && !ref.current.contains(event.target as Node)) {
      setIsOpen(false);
    }
  };

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

  return (
    <div ref={ref}>
      {isOpen ? (
        <div> {children}</div>
      ) : (
        <button onClick={() => setIsOpen(true)}>Open</button>
      )}
    </div>
  );
};

export default OutsideClick;

Enter fullscreen mode Exit fullscreen mode

This implementation listens for click events on the document and checks if the clicked element is outside the component's ref using the contains method.

2. Using a Third-Party Library (React Outside Click)

If you prefer using a third-party library, there's a popular one called react-outside-click-handler. Here's how you can use it:

First, install the library:

npm install react-detect-click-outside

Then, use it in your component:

import React from "react";
import { useDetectClickOutside } from "react-detect-click-outside";

const OutsideClick = ({ closeDropdown }) => {
  const ref = useDetectClickOutside({ onTriggered: closeDropdown });
  return (
    <div className="dropdown" ref={ref}>
      <p>This is a dropdown!</p>
    </div>
  );
};

export default OutsideClick;

Enter fullscreen mode Exit fullscreen mode

This library simplifies the process by providing hooks as a wrapper component that handles the outside click event for you.

3. Using Event Bubbling (No Refs)

Another way to implement an "outside click" feature is by leveraging event bubbling in React. Here's an example:

import React, { useState } from "react";

const OutsideClick = ({ children }) => {
  const [isOpen, setIsOpen] = useState(false);

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

  const handleClickInside = (event) => {
    event.stopPropagation();
    setIsOpen(true);
  };

  return (
    <div onClick={handleClickOutside}>
      {isOpen ? (
        <div onClick={handleClickInside}>{children}</div>
      ) : (
        <button onClick={() => setIsOpen(true)}>Open</button>
      )}
    </div>
  );
};

export default OutsideClick;
Enter fullscreen mode Exit fullscreen mode

4. Making Custom Hooks (almost same concept)

In this sophisticated way, we are presently engendering a React custom hook, one that bears striking semblance to the concept expounded earlier:

import { useEffect } from "react";

const useOutsideClick = (ref, callback) => {
  useEffect(() => {
    function handleClickOutside(event) {
      if (ref.current && !ref.current.contains(event.target)) {
        callback();
      }
    }

    document.addEventListener("click", handleClickOutside);

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

export default useOutsideClick;
Enter fullscreen mode Exit fullscreen mode

Conclusion

Recognizing the nuances of user interface design, the judicious use of outside click detection proves highly beneficial in a variety of UI elements such as popups, dropdowns, and menus. It is a wise practice to note that web developers frequently lean towards integrating third-party libraries for tasks that can be handled independently.

This preference for excessive dependencies can lead to the unnecessary burden on web applications, resulting in larger bundle sizes and a detrimental effect on codebase maintainability.

Top comments (0)