Creating Submenus I find that when opening one of them all the others open and when closing it in the same way they all close.
This is my code:
const DashBoard = () => {
const [showDropdown, setShowDropdown] = useState(false)
return (
<>
<div>
<div>
<div>
<img
src={ Logo }
alt= "LOGO"
/>
</div>
<div>
<ul>
<li>
<div
onClick={ () => setShowDropdown(!showDropdown) }
>
<FiHome />
Submenu 1
</div>
{ showDropdown &&
(
<div>
<ul>
<li>Test</li>
<li >Test</li>
</ul>
</div>
)
}
</li>
</ul>
</div>
<div>
<ul>
<li className='group'>
<div
onClick={ () => setShowDropdown(!showDropdown) }
>
<FiHome />
Submenu 2
</div>
{ showDropdown &&
(
<div>
<ul>
<li>Test</li>
<li >Test</li>
</ul>
</div>
)
}
</li>
</ul>
</div>
</div>
<div>
<main>Main Content</main>
</div>
</div>
</>
)
}
How could I achieve that when opening a submenu the others are closed? I have reviewed that indicating an ID per submenu is possible but I don't know if it is the best way. Thanks.
CodePudding user response:
setShowDropdown(!showDropdown)
This part is making all your dropdowns closed together. And your showDropdown
state is only true/false value that cannot help you in identifying which dropdown is open/closed
I'd propose that you should assign menu item name to the state
const [showDropdown, setShowDropdown] = useState() //as default, no menu items are opening
According to your setup, I'd use your sub-menu name for the state value
setShowDropdown("Submenu 1")
onClick
logic for opening/closing a sub-menu item
onClick={() => setShowDropdown(showDropdown === "Submenu 2" ? undefined : "Submenu 2")}
Add the condition to check current open/closed sub-menu items
showDropdown === "Submenu 1"
Full implementation can be
const DashBoard = () => {
const [showDropdown, setShowDropdown] = useState()
return (
<>
<div>
<div>
<div>
<img
src={ Logo }
alt= "LOGO"
/>
</div>
<div>
<ul>
<li>
<div
onClick={ () => setShowDropdown(showDropdown === "Submenu 1" ? undefined : "Submenu 1") }
>
<FiHome />
Submenu 1
</div>
{ showDropdown === "Submenu 1" &&
(
<div>
<ul>
<li>Test</li>
<li >Test</li>
</ul>
</div>
)
}
</li>
</ul>
</div>
<div>
<ul>
<li className='group'>
<div
onClick={ () => setShowDropdown(showDropdown === "Submenu 2" ? undefined : "Submenu 2") }
>
<FiHome />
Submenu 2
</div>
{ showDropdown === "Submenu 2" &&
(
<div>
<ul>
<li>Test</li>
<li >Test</li>
</ul>
</div>
)
}
</li>
</ul>
</div>
</div>
<div>
<main>Main Content</main>
</div>
</div>
</>
)
}
CodePudding user response:
It would be good if you make it all dynamic using an array.
Here I have taken an array named menu
which includes 3 properties title, visible, and child
. And in the HTML, I have used the visible
property to show the respective menu's child.
Demo: https://stackblitz.com/edit/react-3w2rns
Solution:
import React, { useState } from 'react';
import './style.css';
export default function App() {
const [menu, setMenu] = useState([
{
title: 'Menu 1',
visible: false,
child: [{ title: 'Test 1' }, { title: 'Test 1' }],
},
{
title: 'Menu 2',
visible: false,
child: [{ title: 'Test 2' }, { title: 'Test 2' }],
},
]);
const onMenuClick = (index) => {
menu[index].visible = !menu[index].visible;
setMenu([...menu]);
};
return (
<>
<div>
<div>
<div>
<img src="" alt="LOGO" />
</div>
{menu.map((menu, index) => (
<div>
<ul>
<li className="group">
<div onClick={() => onMenuClick(index)}>{menu.title}</div>
{menu.visible && (
<ul>
{menu.child.map((item) => (
<li>{item.title}</li>
))}
</ul>
)}
</li>
</ul>
</div>
))}
</div>
<div>
<main>Main Content</main>
</div>
</div>
</>
);
}