Search code examples
htmlreactjsreact-hookstailwind-css

How can I implement a toggle functionality in ReactJS where clicking a function reveals a menu, and clicking outside the menu hides it?


when I click a button the menu will come & in 2nd click or clicking outside the menu will hide. how can I do this using react.Js, useRef()?

I tried & the result showed me that, when I click the menu part or the button, the menu come out but when I click outside it doesn't unhide. t unhide I have to click on that specific button or something. I want when I click the button it will show and when I click another in that button or click anywhere in the webpage it will hide.


Solution

  • To toggle, first use the useRef hook to create a reference to the dropdown div. After that use the useEffect hook to add an event listener for clicks outside the dropdown. On click of outside the dropdown, it checks if the clicked element is inside the dropdown using the contains method. If not, it closes the dropdown.

    The handleToggle toggles the dropdown's visibility when the button is clicked.

    Here's the implementation:

    import React, { useState, useEffect, useRef } from "react";
    
    function App() {
      const [isOpen, setIsOpen] = useState(false);
      const dropdownRef = useRef(null);
    
      useEffect(() => {
        const handleClickOutside = (event) => {
          if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
            setIsOpen(false);
          }
        };
    
        // Add event listener to handle clicks outside the dropdown
        document.addEventListener("mousedown", handleClickOutside);
    
        // Clean up the event listener on component unmount
        return () => {
          document.removeEventListener("mousedown", handleClickOutside);
        };
      }, []);
    
      const handleToggle = () => {
        setIsOpen((prev) => !prev);
      };
    
      return (
        <div ref={dropdownRef} className="dropdown">
          <button onClick={handleToggle}>Toggle Dropdown</button>
          {isOpen && (
            <div className="dropdown-content">
              {/* Dropdown content goes here */}
              <p>Dropdown content goes here</p>
            </div>
          )}
        </div>
      );
    }
    
    export default App;