DEV Community

Cover image for Click Outside Magic: a new Custom Hook!
Nicolas B.
Nicolas B.

Posted on • Edited on

Click Outside Magic: a new Custom Hook!

Performance is a crucial aspect of web application development, and ensuring a smooth user experience often involves detecting user interactions or element visibility. In this article, I'll introduce you to a custom React hook called useClickOutside. This hook simplifies the process of detecting clicks outside a specified element, a common requirement for implementing features like modals, dropdowns, or popovers. By leveraging useClickOutside, you can significantly improve the user experience in your React applications.


Introducing useClickOutside

The useClickOutside hook is designed to determine whether a user has clicked outside a specific element in a React application. It helps in scenarios where you want to close a modal, hide a dropdown, or dismiss a popover when the user clicks outside of the relevant component. The hook is straightforward and leverages the React useRef and useEffect functions.

Here's how the useClickOutside hook works:

import { RefObject, useEffect } from 'react';

export const useClickOutside = (
  ref: RefObject<HTMLElement>,
  handleOnClickOutside: (event: MouseEvent | TouchEvent) => void
) => {
  useEffect(() => {
    const listener = (event: MouseEvent | TouchEvent) => {
      if (!ref.current || ref.current.contains(event.target as Node)) {
        return;
      }
      handleOnClickOutside(event);
    };
    document.addEventListener('mousedown', listener);
    document.addEventListener('touchstart', listener);
    return () => {
      document.removeEventListener('mousedown', listener);
      document.removeEventListener('touchstart', listener);
    };
  }, [ref, handleOnClickOutside]);
}
Enter fullscreen mode Exit fullscreen mode

How to Use useClickOutside

Let's look at an example of using the useClickOutside hook to close a modal when a user clicks outside of it:

import React, { useRef } from 'react';
import { useClickOutside } from './useClickOutside';

function Modal() {
  const modalRef = useRef();

  // State to manage modal visibility
  const [isOpen, setIsOpen] = useState(true);

  // Function to close the modal
  const closeModal = () => {
    setIsOpen(false);
  };

  // Attach the click outside listener to the modal
  useClickOutside(modalRef, closeModal);

  return (
    <div ref={modalRef} className={`modal ${isOpen ? 'open' : 'closed'}`}>
      <div className="modal-content">
        <p>Click outside to close this modal</p>
      </div>
    </div>
  );
}

function App() {
  return (
    <div className="app">
      <h1>React Click Outside Example</h1>
      <Modal />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

In this example, the useClickOutside hook is applied to the Modal component, and it listens for clicks outside the modal's content. When a click occurs outside the modal, the closeModal function is called, which toggles the modal's visibility. This is just one of the many ways you can use the useClickOutside hook to enhance user interactions in your React applications.

In conclusion, the useClickOutside hook simplifies the process of handling click events outside a specific element, making your React application more user-friendly and performant. You can easily integrate this custom hook into your projects to provide a better user experience and optimize performance.

Top comments (2)

Collapse
 
pimp_my_ruby profile image
Pimp My Ruby

Thanks !

Collapse
 
revidovich profile image
Anna

useClickOutside(!isOpen ? modalRef : parentRef, toggleMenu); -- I like it! Thank you!