Así que estoy haciendo este proyecto en ReactJs, que tiene una barra lateral, donde intento implementar el menú desplegable.
Comportamiento requerido
Si hago clic en cualquiera de las opciones de la barra lateral, si tiene un submenú, se mostrará. Y cerrar al hacer clic de nuevo.
Comportamiento actual
Si hago clic en cualquiera de las opciones, todos los submenús se muestran a la vez. Por ejemplo, si hago clic en la opción de publicaciones, me muestra todas las opciones, como publicaciones destacadas, publicaciones de revistas. ¿Cómo arreglo eso?
Mi matriz sidebarItems
const sidebarItems = [ { title: "Publications", url: "#", subMenu: [ { title: "Journal Publications", url: "#", }, { title: "Featured Publications", url: "#", }, ], }, { title: "Team Members", url: "#", subMenu: [ { title: "Current Members", url: "#", }, { title: "Lab Alumni", url: "#", }, ], }, { title: "Projects", url: "#", subMenu: [ { title: "Project 1", url: "#", }, { title: "Project 2", url: "#", }, { title: "Project 3", url: "#", }, ], }, { title: "News", url: "#", }, { title: "Contact Us", url: "#", }, ]; export default sidebarItems;El componente de la barra lateral
import { useState } from "react"; import { Box, Text } from "@chakra-ui/react"; import sidebarItems from "./sidebarItems"; export default function Sidebar() { const [isOpen, setIsOpen] = useState(false); return ( <div> <Box> {sidebarItems.map((items) => { return ( <Box width='200px' height='40px' textAlign='center' cursor='pointer' onClick={() => { setIsOpen(!isOpen); }} > <Text>{items.title}</Text> {isOpen ? items.subMenu?.map((item) => { return <Text>{item.title}</Text>; }) : ""} </Box> ); })} </Box> </div> ); }Tienes que usar una variable de estado de matriz. Su variable de estado único isOpen está dictando todos los submenús aquí:
{isOpen ? items.subMenu?.map((item) => { return <Text>{item.title}</Text>; }) : ""} Debe tener una variable de estado de matriz aquí, por lo que cada elemento de la barra lateral tiene un valor boolean correspondiente para dictar la apertura/cierre del valor.
const [isOpen, setIsOpen] = useState(Array(sidebarItems.length).fill(false));Ahora debe asegurarse de configurarlo correctamente y manipular el elemento de matriz correcto.
onClick={() => { let newIsOpen = [...isOpen]; newIsOpen[index] = !isOpen[index]; setIsOpen(newIsOpen); }}Espero que esto te ayude a llegar a tu solución.
Creo que el problema ocurre porque solo tiene 1 variable de estado establecida para cada opción de la barra lateral. Cada opción de la barra lateral debe tener su propia variable que realice un seguimiento de si su submenú debe abrirse o no.
En su código, cuando la variable de estado isOpen se establece en verdadero, cuando la función asigna todas las opciones, el valor de la variable siempre será verdadero.
Intente configurar una variable para cada una de las opciones del menú que contenga si el submenú debe abrirse o no.
Esto sucede porque está utilizando una lógica incorrecta y no especifica qué submenú debe mostrarse. Primero, elimine el estado actual y no lo use. Luego, debe definir otro estado como:
const [selectedMenu, setSelectedMenu] = useState("");entonces, define esta función:
const handleClick = (title) => { setSelectedMenu(title); }después de eso, una vez que haga clic en Cuadro, debe invocar una función como esta:
onClick={() => handleClick(item.title)}en consecuencia, debe escribir su lógica de esta manera:
<Text>{items.title}</Text> {item.title === selectedMenu ? items.subMenu?.map((item) => { return <Text>{item.title}</Text>; }) : ""}