Home > Back-end >  How to make dropdown close or open when I click on the button when there is ref used? (React)
How to make dropdown close or open when I click on the button when there is ref used? (React)

Time:04-18

I have this issue that when I want to close my dropdown menu that opens when I click on the hamburger menu, it doesn't want to close when I click on the button again, the reason why it doesn't work is because I added the functionality to close the dropdown when I click outside the dropdown. I created that functionality with using ref from React.

Here is my code:

const Navbar = () => {
  const [open, setOpen] = useState(false);

  const ref = useRef();

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

  return (
    <div className="navbar_container">
      <div className="navbar_inner_container">
        <div className="logo_container">
          <img src={Logo} alt="logo" className="navbar_logo" />
        </div>
        <div
          className="hamburger_menu"
          onClick={() => {
            setOpen(!open);
          }}
        >
          <Dropdown open={open} dropdownRef={ref} />
        </div>
      </div>
    </div>
  );
};

export default Navbar;

const Dropdown = ({ open, dropdownRef }) => {
  return (
    <div ref={dropdownRef}>
      {open === true ? (
        <div className="dropdown_container">
          <div
            className="dropdown_item"
            onClick={() =>
              window.scrollTo({
                top: document.getElementsByClassName("functions_container")[0]
                  .offsetTop,
                behavior: "smooth",
              })
            }
          >
            <button className="navbar_link">Functions</button>
          </div>
          <div
            className="dropdown_item"
            onClick={() =>
              window.scrollTo({
                top: document.getElementsByClassName("partners_container")[0]
                  .offsetTop,
                behavior: "smooth",
              })
            }
          >
            <button className="navbar_link">Partner</button>
          </div>
          <div
            className="dropdown_item"
            onClick={() =>
              window.scrollTo({
                top: document.getElementsByClassName("statements_container")[0]
                  .offsetTop,
                behavior: "smooth",
              })
            }
          >
            <button className="navbar_link">Statements</button>
          </div>
          <div
            className="dropdown_item"
            onClick={() =>
              window.scrollTo({
                top: document.getElementsByClassName("contact_container")[0]
                  .offsetTop,
                behavior: "smooth",
              })
            }
          >
            <button className="navbar_link">Contact</button>
          </div>
          <img
            src={LanguageFlag}
            alt="lanugage_flag"
            className="language_flag"
          />
        </div>
      ) : null}
    </div>
  );
};

export default Dropdown;

Does anyone know what is the reason for the dropdown not closing when I press on the hamburger button again, as far as I know by using the !open it should close.

CodePudding user response:

It will be triggering both functions at the same time. Which causes problems. You Have to Include the Hamburger button also in the ref.

  const Navbar = () => {
  const [open, setOpen] = useState(false);

  const ref = useRef();

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

  return (
    <div className="navbar_container">
      <div className="navbar_inner_container">
        <div className="logo_container">
          <img src={Logo} alt="logo" className="navbar_logo" />
        </div>
        <section ref={ref}>
        <div
          className="hamburger_menu"
          onClick={() => {
            setOpen(!open);
          }}
        >
          <Dropdown open={open}  />
        </div>
</section>
      </div>
    </div>
  );
};

export default Navbar;

const Dropdown = ({ open }) => {
  return (
    <div >
      {open === true ? (
        <div className="dropdown_container">
          <div
            className="dropdown_item"
            onClick={() =>
              window.scrollTo({
                top: document.getElementsByClassName("functions_container")[0]
                  .offsetTop,
                behavior: "smooth",
              })
            }
          >
            <button className="navbar_link">Functions</button>
          </div>
          <div
            className="dropdown_item"
            onClick={() =>
              window.scrollTo({
                top: document.getElementsByClassName("partners_container")[0]
                  .offsetTop,
                behavior: "smooth",
              })
            }
          >
            <button className="navbar_link">Partner</button>
          </div>
          <div
            className="dropdown_item"
            onClick={() =>
              window.scrollTo({
                top: document.getElementsByClassName("statements_container")[0]
                  .offsetTop,
                behavior: "smooth",
              })
            }
          >
            <button className="navbar_link">Statements</button>
          </div>
          <div
            className="dropdown_item"
            onClick={() =>
              window.scrollTo({
                top: document.getElementsByClassName("contact_container")[0]
                  .offsetTop,
                behavior: "smooth",
              })
            }
          >
            <button className="navbar_link">Contact</button>
          </div>
          <img
            src={LanguageFlag}
            alt="lanugage_flag"
            className="language_flag"
          />
        </div>
      ) : null}
    </div>
  );
};

export default Dropdown;

CodePudding user response:

const [open, setOpen] = useState(false)

 const showHide = () => setOpen(!open)
     
const closeDivFromeParent = () => setOpen(false)


{`open?<div>you content to be hide and shown</div>:null}`

Then call showHide function from your humberger Icon.

If you want to close the popup from it's parent div call closeDivFromeParent

Happy coding!

  • Related