【问题标题】:App bar menu items not opening correct sub menu应用栏菜单项未打开正确的子菜单
【发布时间】:2019-06-03 16:58:58
【问题描述】:

我正在使用 React16 和 Material UI 库构建一个前端应用程序。

我正在尝试在顶部构建一个简单的导航栏,其中包含多个菜单项。我从material-ui.com网站上拿了“简单菜单”的例子。

我尝试在应用栏中添加第二个菜单项。

但是,单击任一菜单项会打开profile-menu 的子菜单。所以换句话说,点击simple-menu 会打开个人资料、我的帐户和注销,但它应该会打开新建、列表和报告。

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;

【问题讨论】:

  • 您应该将 open 定义为您映射到的常量类型。因此,例如 open={!!anchorEl &amp;&amp; anchorEl === 'profile'} 仅供参考,!! 是比类型构造函数 Boolean 更好的布尔检查
  • @JohnRuddell 谢谢!试过了,但它似乎不起作用。现在两个菜单都不会打开。 ` ` .
  • 让我写一个解决方案,因为你必须对 anchorEl 应用相同的值

标签: reactjs material-ui


【解决方案1】:

首先你需要在一个枚举/对象中定义菜单

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

添加另一个状态项来跟踪您的活动菜单

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

然后更新handleMenu 以接受菜单类型并将其设置为状态。 如果 menuType 将是第一个或第二个参数,我不记得了,所以验证一下。

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

那么你的点击回调需要反映正确的菜单

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

然后你需要引用那个类型来确定当前是活跃的

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

不要忘记更新关闭处理程序

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

如果这里有什么不明白的地方,请告诉我,我会尝试更详细地解释令人困惑的地方:)

【讨论】:

  • 谢谢!我现在看到这个错误:index.js:1375 Warning: Failed prop type: Invalid prop anchorEl` 提供给ForwardRef(Menu) 我确认 menuType 是第一个参数,它在 console.log 中显示了正确的值。
  • anchorEl 应该是什么?意思是菜单想要的道具?在将 currentTarget 与这些更改一起存储方面,可能需要做您之前所做的事情
  • @pengz 让我更新我的答案,您需要实际跟踪两者
  • @pengz 试一试
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-09
相关资源
最近更新 更多