简体   繁体   中英

How do i implement a dropdown header in Material-ui in react?

My main problem is that it's only rendering the last Menu Dropdown but i need different Menus (and you can see the text behind it faintly appearing). Am unsure how to pass the correct props / state to enable this

import React from 'react';
import {Button, Menu, MenuItem} from "@material-ui/core";

function Header(){
const [anchorEl, setAnchorEl] = React.useState(null);

const handleClick = (event) => {
    setAnchorEl(event.currentTarget);
};

const handleClose = () => {
    setAnchorEl(null);
};

return (
    <div>
        <Button aria-controls="sessions-menu" aria-haspopup="true" onClick={handleClick}>
            Sessions
        </Button>
        <Button aria-controls="store-menu" aria-haspopup="true" onClick={handleClick}>
            Store
        </Button>
        <Button aria-controls= "about-menu" aria-haspopup="true" onClick={About} href="/about">
            About
        </Button>
        <Button aria-controls="account-menu" aria-haspopup="true" onClick={handleClick}>
            Account
        </Button>
        <Menu
            id="sessions-menu"
            anchorEl={anchorEl}
            getContentAnchorEl={null}
            keepMounted
            open={Boolean(anchorEl)}
            onClose={handleClose}
        >
            <MenuItem onClick={Book} href="/sessions/book">Book a Session</MenuItem>
            <MenuItem onClick={Host} href="/sessions/host">[S] Host a session</MenuItem>
        </Menu>
        <Menu
            id="store-menu"
            anchorEl={anchorEl}
            getContentAnchorEl={null}
            keepMounted
            open={Boolean(anchorEl)}
            onClose={handleClose}
        >
            <MenuItem onClick={Purchase}>Purchase</MenuItem>
            <MenuItem onClick={Sell}>[S] Sell</MenuItem>
        </Menu>
        <Menu
            id="about-menu"
            anchorEl={anchorEl}
            keepMounted
            open={Boolean(anchorEl)}
            onClose={handleClose}
        ></Menu>
        <Menu
            id="account-menu"
            anchorEl={anchorEl}
            keepMounted
            open={Boolean(anchorEl)}
            onClose={handleClose}
        >
            <MenuItem onClick={Lessons}>My Lessons</MenuItem>
            <MenuItem onClick={Items}>My Purchases</MenuItem>
        </Menu>
    </div>
);
}
export default Header;

Any help or advice for a simpler way to achieve what i want would be swell

As given in documentation anchorEl - It's used to set the position of the menu. In your code you used same anchorEl for all menu and as a result it's only rendering the last Menu Dropdown.

solution is to have anchorEl separate to each menu. for that you need to create scoped MenuButton component for each button with its menu .

You can have separate component for each button with its menu (duplication) however it better have an array of menus and render it with single component(reusability).

please check running code here https://codesandbox.io/s/header-menu-dropdown-e9e7p

I will put Header and MenuButton code here if link not work.

Header.js

import React from "react";
import MenuButton from "./MenuButton";

const Header = () => {
  //added only two menu to demonstrate you can add more as per your requirement
  const menu = [
    {
      name: "Sessions",
      menuItems: [
        {
          name: "Book a Session",
          onClick: () => {},
          href:"" 
        },
        {
          name: "[S] Host a session",
          onClick: () => {},
          href:"" 
        }
      ]
    },
    {
      name: "Store",
      menuItems: [
        {
          name: "Purchase",
          onClick: () => {}
        },
        {
          name: "Sell",
          onClick: () => {}
        }
      ]
    }
  ];
  return menu.map((item, index) => <MenuButton key={index} menu={item} />);
};
export default Header;

MenuButton.js ( button with its menu )

import React from "react";
import { Button, Menu, MenuItem } from "@material-ui/core";

const MenuButton = ({ menu }) => {
  const [anchorEl, setAnchorEl] = React.useState(null);

  const handleClick = (event) => {
    setAnchorEl(event.currentTarget);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  return (
    <>
      <Button
        aria-controls={`${menu.name}-menu`}
        aria-haspopup="true"
        onClick={handleClick}
      >
        {menu.name}
      </Button>
      <Menu
        id={`${menu.name}-menu`}
        anchorEl={anchorEl}
        getContentAnchorEl={null}
        keepMounted
        open={Boolean(anchorEl)}
        onClose={handleClose}
      >
        {menu.menuItems.map((item) => (
          <MenuItem onClick={item.onClick} href={item.href}>
            {item.name}
          </MenuItem>
        ))}
      </Menu>
    </>
  );
};
export default MenuButton;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM