KornelDev96
KornelDev96

Reputation: 59

Dropdown menu how hide elements on click and display only one?

I have a quastion how to manipulate state in my dropdown menu? I mean that now when i click one element (for example "Mezczyzna" - ItemsMenu - MenuItem) my item shows up and when i click another item (for example "Kobieta"-ItemsMenu - MenuItem (Kobieta is title)) this item also shows up and "Mezczyzna" is still open but i want to hide "Mezczyzna". I dont know how to setState for element with specific index for example. Now i have parent file - Navigationn which renders (map) ItemsMenu with state. How can i setState[2]element to false? Thanks for the help :)

const Navigationn = ({displayHandlerMenu}) =>{
return (
<>
  <SidebarWrap>
    {menuItems.map((item, index) => (
      <ItemsMenu key={index} item={item} displayHandlerMenu={displayHandlerMenu} />
    ))}
  </SidebarWrap>
</>);};
export default Navigationn;



const ItemsMenu = ({ item, displayHandlerMenu, index }) =>{
const [submenu, setSubmenu] = useState(false);
const showSubmenu = () => {
setSubmenu(!submenu);};
return (
<>
  <MenuItemLink to={item.path} onClick={showSubmenu} key={index}>
    <MenuItem>{item.title}</MenuItem>
  </MenuItemLink>
  {item.submenu &&
    submenu &&
    item.submenu.map((subItem, index) => (
      <>
        <ItemsSubMenu
          key={index}
          item={subItem}
          displayHandlerMenu={displayHandlerMenu}
        />
      </>
    ))}
</>
);};
export default ItemsMenu;

Upvotes: 0

Views: 121

Answers (1)

Omer Setty
Omer Setty

Reputation: 208

A simple way to achieve this is to store the current chosen item id (it better be a unique property, here for the simplicity I chose the title) as a state in the parent component (Navigationn), and to pass this state as props (using Context is also an option) to the children.

Each child component (ItemsMenu) shows his sub-items only if the current item title is his title, and set the current item title to his title when clicked (if it's already his title - change it to null so no item will be shown).

const Navigationn = ({ displayHandlerMenu }) => {
  const [currentShownItemId, setCurrentShownItemId] = useState();

  return (
    <>
      <SidebarWrap>
        {menuItems.map((item, index) => (
          <ItemsMenu key={index} item={item} displayHandlerMenu={displayHandlerMenu} 
            currentShownItemId={currentShownItemId} setCurrentShownItemId={setCurrentShownItemId}/>
        ))}
      </SidebarWrap>
    </>);
};

const ItemsMenu = ({ item, displayHandlerMenu, index, currentShownItemId, setCurrentShownItemId }) => {
  const showSubmenu = () => {
    setCurrentShownItemId(currentShownItemId === item.title ? null : item.title);
  };
  return (
    <>
      <MenuItemLink to={item.path} onClick={showSubmenu} key={index}>
        <MenuItem>{item.title}</MenuItem>
      </MenuItemLink>
      {item.submenu &&
        currentShownItemId === item.title &&
        item.submenu.map((subItem, index) => (
          <>
            <ItemsSubMenu
              key={index}
              item={subItem}
              displayHandlerMenu={displayHandlerMenu}
            />
          </>
        ))}
    </>
  );
};

Upvotes: 1

Related Questions