Estoy tratando de evitar que el botón vuelva a hacer clic una vez que el menú desplegable está habilitado desde que se hace clic en el botón. clics de botón -> abre menú desplegable. la única forma en que el menú puede cerrarse es con un clic externo, y no desde el botón, es decir, desde useOnClickOutside "usehooks-ts". El botón solo debe poder hacer clic y abrir el menú si el menú está cerrado. gracias de antemano si alguien puede ayudar con el problema.
https://codesandbox.io/s/funny-wilson-4wbj0?file=/src/App.js (aquí está el sandbox, pero tailwindcss npm no funciona).
import React, { useRef, useState } from "react"; import { useOnClickOutside } from "usehooks-ts"; export const DropDownMenu = () => { const ref = useRef(null); const [showMenu, setShowMenu] = useState(false); const handleClick = () => setShowMenu(!showMenu); const handleClickOutside = () => setShowMenu(false); useOnClickOutside(ref, handleClickOutside); return ( <div className="mt-20"> <button onClick={handleClick} className="bg-yellow-300 ml-5 text-sm2 border-solid border-2 border-blue-300" > <div>Open Menu</div> </button> <div ref={ref} className={`absolute top-8 w-240 opacity-0 bg-red-200 ml-20 ${showMenu ? "opacity-100 visible" : ""}`} > <ul> <li className="">Menu Item One</li> <li className="">Menu Item Two</li> <li className="">Menu Item Three</li> </ul> </div> </div> ); }; export default DropDownMenu;Agregue la condición en handleClick, para verificar si showMenu es falso y luego continúe:
const handleClick = () => !showMenu && setShowMenu(!showMenu);Deja de pensar demasiado en las cosas. Simplemente coloque la referencia en el componente principal del botón y el menú desplegable, para que no detecte los componentes secundarios :)
import React, { useRef, useState } from "react"; import { useOnClickOutside } from "usehooks-ts"; export const DropDownMenu = () => { const ref = useRef(null); const [showMenu, setShowMenu] = useState(false); const handleClick = () => setShowMenu(!showMenu); const handleClickOutside = () => setShowMenu(false); useOnClickOutside(ref, handleClickOutside); return ( <div className="mt-20" ref={ref}> // Place ref here <button onClick={handleClick} className="bg-yellow-300 ml-5 text-sm2 border-solid border-2 border-blue-300" > <div>Open Menu</div> </button> <div className={`absolute top-8 w-240 opacity-0 bg-red-200 ml-20 ${showMenu ? "opacity-100 visible" : ""}`} > <ul> <li className="">Menu Item One</li> <li className="">Menu Item Two</li> <li className="">Menu Item Three</li> </ul> </div> </div> ); }; export default DropDownMenu;