I tried but i can't. Do I need to create separate function for each dropdown? I think there should be a brevity. I want other open dropdowns to close when the user clicks on a dropdown. I hope someone can help me. it took me a long time still i couldn't find any result. this way i will add 2 more dropdown menus.
import React, { useState } from "react";
export const AsideItems = () => {
const [menuOpened, setMenuOpened] = useState(false);
const [menuOpenedSecond, setMenuOpenedSecond] = useState(false);
const handleMenu = () => {
setMenuOpened((menuOpened) => !menuOpened);
};
const handleMenuSecond = () => {
setMenuOpenedSecond((menuOpenedSecond) => !menuOpenedSecond);
};
return (
<>
<li className="tree-item">
<a className="tree-link" href="/">
Computers & Laptops
</a>
<span
onClick={handleMenu}
className={`list-icon${menuOpened ? " " : " open-list"}`}
>
+
</span>
<span
onClick={handleMenu}
className={`list-icon${menuOpened ? " open-list" : " "}`}
>
-
</span>
<div className={`sub-menu${menuOpened ? " open-sub" : " "}`}>
<ul className="sub-nav">
<li className="sub-item">
<a href="/" className="sub-link">
Computer Accessories
</a>
</li>
</ul>
</div>
</li>
<li className="tree-item">
<a className="tree-link" href="/">
Game Consoles
</a>
<span
onClick={handleMenuSecond}
className={`list-icon${menuOpenedSecond ? " " : " open-list"}`}
>
+
</span>
<span
onClick={handleMenuSecond}
className={`list-icon${menuOpenedSecond ? " open-list" : " "}`}
>
-
</span>
<div className={`sub-menu${menuOpenedSecond ? " open-sub" : " "}`}>
<ul className="sub-nav">
<li className="sub-item">
<a href="/" className="sub-link">
Consoles
</a>
</li>
</ul>
</div>
</li>
</>
);
};
Instead of using multiple boolean state values, you can use a single state value that holds the name (or index) of the open menu. This way you only need one state variable and only one menu can be open at a time. To indicate that no menu is open, you can set the state value to null.
Here's an example:
const menuNames = {
first: "first",
second: "second",
// ...
}
export const AsideItems = () => {
const [openMenuName, setOpenMenuName] = React.useState(null);
return (
<>
<span
onClick={() => setOpenMenuName(menuNames.first)}
className={`list-icon${openMenuName === menuNames.first ? " " : " open-list"}`}
>
+
</span>
<span
onClick={() => setOpenMenuName(menuNames.second)}
className={`list-icon${openMenuName === menuNames.second ? " " : " open-list"}`}
>
+
</span>
</>
)
}
Note you don't have to define an object containing the menu names, but it's safer than just using string literals.