Soy nuevo en React JS y estoy creando un menú de barra lateral con submenú para mi proyecto.
Problema : cuando intento abrir el submenú, todos los submenús se abren.
Aquí está el Codesandbox
Estoy abierto a otras soluciones también. Cualquier ayuda es muy apreciada. Gracias de antemano.
Aplicación.js
import Menu from "./components/Menu/Menu"; export default function App() { return <Menu />; }Menú.js
import React, {useState} from 'react' import SubMenu from './SubMenu' import MenuItems from './menuData' const Menu = () => { const [toggle, setToggle] = useState(false) const clickHandler = () => { console.log(`clicked`) setToggle(!toggle) } return ( <nav> <ul> { MenuItems.map((item) => { return ( <li key={item.menuname} onClick={item.submenu && clickHandler}> {item.menuname} {item.submenu && toggle ? <SubMenu dropDownItem={item.submenu} /> : null} </li> ) }) } </ul> </nav> ) } export default MenuSubMenú.js
import React from 'react' const SubMenu = ({dropDownItem}) => { return ( <div className='drop-down'> <ul> {dropDownItem.map((item) => { return <li key={item.submenuname}>{item.submenuname}</li> })} </ul> </div> ) } export default SubMenumenuData.js
const MenuItems = [ { "menuname": 'Home', "submenu": [ {"submenuname": "Home Child 1"}, {"submenuname": "Home Child 2"}, {"submenuname": "Home Child 3"} ] }, { "menuname": 'About', "submenu": [ {"submenuname": "About Child 1"}, {"submenuname": "About Child 2"}, {"submenuname": "About Child 3"} ] }, { "menuname": 'Contact' } ] export default MenuItemsEl problema ocurre porque tiene un solo estado de alternancia para todos los elementos. Una posible solución podría ser definir el estado en cada ItemMenu individual y luego puede verificar el estado para mostrar u ocultar el elemento del Submenú.
Como esto:
const Menu = () => { return ( <nav> <ul> {MenuItems.map((item) => { return ( <li key={item.menuname}> <MenuItem item={item} /> </li> ); })} </ul> </nav> ); };Y este es el MenuItem:
import React, { useState } from "react"; const MenuItem = ({ item }) => { const [isSubMenuShow, setIsSubMenuShow] = useState(false); return ( <div> <div onClick={() => setIsSubMenuShow(!isSubMenuShow)}> {item.menuname} </div> {item.submenu && isSubMenuShow && <SubMenu dropDownItem={item.submenu} />} </div> ); }; const SubMenu = ({ dropDownItem }) => { return ( <div className="drop-down"> <ul> {dropDownItem.map((item) => { return <li key={item.submenuname}>{item.submenuname}</li>; })} </ul> </div> ); }; export default MenuItem;Espero que esto te haya ayudado.
es porque establece un estado general para controlar los submenús, debe cambiar su estado, por ejemplo, como se muestra a continuación
const [toggle, setToggle] = useState(null) const clickHandler = (menuId) => { console.log(`clicked`) setToggle(menuId) } return ( <nav> <ul> { MenuItems.map((item) => { return ( <li key={item.menuname} onClick={clickHandler(item.id)}> {item.menuname} {item.submenu && toggle == item.id ? <SubMenu dropDownItem={item.submenu} /> : null} </li> ) }) } </ul> </nav> ) }Le di un ejemplo y puede establecer cualquier valor único en lugar de la identificación del elemento y pasárselo a su controlador para establecerlo en su estado
Necesita una matriz para cada índice de submenú y darle un índice de perspectiva.
import React, {useState} from 'react' import SubMenu from './SubMenu' import MenuItems from './menuData' const Menu = () => { const [toggle, setToggle] = useState([]) const clickHandler = (i) => { let tempToggle = [...toggle] if(tempToggle[i]){ tempToggle[i]=false } else{ tempToggle[i]=true } setToggle(tempToggle) } return ( <nav> <ul> { MenuItems.map((item,i) => { return ( <li key={item.menuname} onClick={item.submenu && clickHandler}> {item.menuname} {item.submenu && toggle[i] ? <SubMenu dropDownItem={item.submenu} /> : null} </li> ) }) } </ul> </nav> ) } export default Menu