pengz
pengz

Reputation: 2471

App bar menu items not opening correct sub menu

I am building a front-end application using React16 and the Material UI library.

I am trying to build a simple navigation bar at the top containing multiple menu items. I took the "simple menu" example from the material-ui.com website.

I tried to add a second menu item in the app bar.

However, clicking on either one of the menu items opens the sub-menus for profile-menu. So in other words clicking on simple-menu opens up Profile, My Account, and Logout but it should open up New, List, and Report.

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import IconButton from '@material-ui/core/IconButton';
import AccountCircle from '@material-ui/icons/AccountCircle';
import Button from '@material-ui/core/Button';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import MenuIcon from '@material-ui/icons/Menu';

const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1,
  },
  menuButton: {
    marginRight: theme.spacing(2),
  },
  title: {
    flexGrow: 1,
  },
}));

function MenuAppBar() {
  const classes = useStyles();
  const [auth, setAuth] = React.useState(true);
  const [anchorEl, setAnchorEl] = React.useState(null);
  const open = Boolean(anchorEl);

  function handleMenu(event) {
    setAnchorEl(event.currentTarget);
  }

  function handleClose() {
    setAnchorEl(null);
  }

  return (
    <div className={classes.root}>
      <AppBar color="default" position="static">
        <Toolbar>
          <Typography variant="h6" className={classes.title}>
            App
          </Typography>
          {auth && (
            <div>
              <Button
                aria-owns={anchorEl ? 'simple-menu' : undefined}
                aria-haspopup="true"
                onClick={handleMenu}
              >
                Open Menu
              </Button>
              <Menu id="simple-menu" anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleClose}>
                <MenuItem onClick={handleClose}>New</MenuItem>
                <MenuItem onClick={handleClose}>List</MenuItem>
                <MenuItem onClick={handleClose}>Report</MenuItem>
              </Menu>
            </div>
          )}
          {auth && (
            <div>
              <IconButton
                aria-owns={anchorEl ? 'profile-menu' : undefined}
                aria-haspopup="true"
                onClick={handleMenu}
              >
              <AccountCircle />
              </IconButton>
              <Menu id="profile-menu" anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleClose}>
                <MenuItem onClick={handleClose}>Profile</MenuItem>
                <MenuItem onClick={handleClose}>My account</MenuItem>
                <MenuItem onClick={handleClose}>Logout</MenuItem>
              </Menu>
            </div>
          )}
        </Toolbar>
      </AppBar>
    </div>
  );
}

export default MenuAppBar;

Upvotes: 3

Views: 1185

Answers (1)

John Ruddell
John Ruddell

Reputation: 25842

First you need to define the menus in an enum / object

const MenuTypes = Object.freeze({
    Simple: 'simple',
    Profile: 'profile'
})

Add another state item to track your active menu

const [activeMenu, setActiveMenu] = React.useState(null);

then update handleMenu to accept the menu type and set it in state. I can't remember off the top of my head if the menuType will be the first or second argument so verify this.

function handleMenu(menuType, event) {
  setActiveMenu(menuType);
  setAnchorEl(event.currentTarget);
}

Then your click callbacks need to reflect the correct menu

<Button
  aria-owns={anchorEl ? 'simple-menu' : undefined}
  aria-haspopup="true"
  onClick={handleMenu.bind(null, MenuTypes.Simple}
>

Then you need to reference that type to determine which is currently active

open={!!activeMenu && activeMenu === MenuTypes.Simple}

Dont forget to update the close handler as well

function handleClose() {
  setActiveMenu(null);
  setAnchorEl(null);
}

Let me know if anything here doesn't make sense and I'll try and explain in more detail what is confusing :)

Upvotes: 2

Related Questions