DEV Community

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

Posted on

3

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.

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

The only thing worse than downtime? No Answers.

If you’re sometimes frustrated with opaque infrastructure, sluggish support, and mysterious outages, we prepared a webinar just for you

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️