Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React closing a dropdown when click outside

Building a custom dropdown in React and came across a problem when trying to close it when clicking outside.
So i created generic HOC so i can use it for other ocasions as well.

The problem i seem to have is i don't know hwo to pass the ref from the hoc to the component.

I've been looking into forwardRef and other tones of examples, but i can't figure it out.
Any idea if it's possible and how i could do it?

Codesandbox Demo

import React, { useState, useRef, useEffect } from "react";

export default function withClickOutside(WrappedComponent) {
  const Component = (props) => {
    const [open, setOpen] = useState(false);

    const ref = useRef();

    useEffect(() => {
      const handleClickOutside = (event) => {
        if (!ref?.current?.contains(event.target)) {
          setOpen(false);
        }
      };
      document.addEventListener("mousedown", handleClickOutside);
    }, [ref]);

    return <WrappedComponent {...props} open={open} setOpen={setOpen} ref={ref}/>;
  };

  return Component;
}

like image 494
Cristian Muscalu Avatar asked Sep 05 '25 03:09

Cristian Muscalu


1 Answers

Simple follow 5 steps to close menu/ change state of any element when clicked outside of that element using React Hook

Step 1 : import useRef and define a variable

import {useRef} from "react"

const catMenu = useRef(null)

Step 2 : use React Hook for state chnage (useState)

  const [openSlide, setopenSlide] = useState(""); 

Step 3 : Define a javascript function to set state

   const closeOpenMenus = (e)=>{
    if(openSlide && !catMenu.current?.contains(e.target)){
      setopenSlide(false)
    }
}

Step 4 : Add a event listener on when mouse is down anywhere in document

 document.addEventListener('mousedown',closeOpenMenus)

Step 5 : Select target element (ref={variable_name})

<div ref={catMenu}>... </div>
like image 199
Aman Gupta Avatar answered Sep 07 '25 23:09

Aman Gupta



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!