如何在React的Material-UI AppBar中为多菜单绑定对应点击触发的MenuItem?
问题解决思路与修改后的代码
这个问题我之前也碰到过!核心原因是你现在用同一个anchorEl状态来管理两个菜单的触发和显示,导致不管点哪个图标,两个菜单都会绑定同一个锚点元素,自然就会出现显示混乱的情况。我给你调整一下代码,让每个菜单独立维护自己的状态:
import React, { Component } from 'react'; // Material UI Imports import { withStyles } from 'material-ui/styles'; import AppBar from 'material-ui/AppBar'; import Toolbar from 'material-ui/Toolbar'; import Typography from 'material-ui/Typography'; import Button from 'material-ui/Button'; import IconButton from 'material-ui/IconButton'; import Tooltip from 'material-ui/Tooltip'; import Menu, { MenuItem } from 'material-ui/Menu'; import PeopleIcon from 'material-ui-icons/People'; import ViewListIcon from 'material-ui-icons/ViewList'; import CompareArrowsIcon from 'material-ui-icons/CompareArrows'; const styles = { root: { width: '100%', }, flex: { flex: 1, }, menuItem: { paddingLeft: '10px' } } class Header extends Component { constructor(props) { super(props); // 给每个菜单单独维护锚点元素状态 this.state = { listMenuAnchor: null, userMenuAnchor: null }; } // 点击菜单图标时,根据传入的菜单类型设置对应的锚点 handleMenu = (event, menuType) => { if (menuType === 'list') { this.setState({ listMenuAnchor: event.currentTarget }); } else if (menuType === 'user') { this.setState({ userMenuAnchor: event.currentTarget }); } } // 关闭菜单时,重置对应菜单的锚点状态 handleClose = (menuType) => { if (menuType === 'list') { this.setState({ listMenuAnchor: null }); } else if (menuType === 'user') { this.setState({ userMenuAnchor: null }); } } render() { const { classes } = this.props; const { listMenuAnchor, userMenuAnchor } = this.state; // 每个菜单的打开状态独立判断 const isListMenuOpen = Boolean(listMenuAnchor); const isUserMenuOpen = Boolean(userMenuAnchor); return( <div className={classes.root}> <AppBar position="static"> <Toolbar> <Typography type="title" color="inherit" className={classes.flex}> New Faces </Typography> {/* Menu Item One - Lists */} <div> <Tooltip title="Lists" className={classes.menuItem}> <IconButton color="inherit" aria-owns={isListMenuOpen ? 'menu-list' : null} aria-haspopup="true" onClick={(e) => this.handleMenu(e, 'list')} > <ViewListIcon /> </IconButton> </Tooltip> <Menu id="menu-list" anchorEl={listMenuAnchor} anchorOrigin={{ vertical: 'top', horizontal:'right', }} transformOrigin={{ vertical: 'top', horizontal:'right', }} open={isListMenuOpen} onClose={() => this.handleClose('list')} > <MenuItem onClick={() => this.handleClose('list')}>Create List</MenuItem> <MenuItem onClick={() => this.handleClose('list')}>List 1</MenuItem> <MenuItem onClick={() => this.handleClose('list')}>List 2</MenuItem> </Menu> </div> {/* Menu Item Two - User Management */} <div> <Tooltip title="User Management" className={classes.menuItem}> <IconButton color="inherit" aria-owns={isUserMenuOpen ? 'menu-appbar' : null} aria-haspopup="true" onClick={(e) => this.handleMenu(e, 'user')} > <PeopleIcon /> </IconButton> </Tooltip> <Menu id="menu-appbar" anchorEl={userMenuAnchor} anchorOrigin={{ vertical: 'top', horizontal:'right', }} transformOrigin={{ vertical: 'top', horizontal:'right', }} open={isUserMenuOpen} onClose={() => this.handleClose('user')} > <MenuItem onClick={() => this.handleClose('user')}>Profile</MenuItem> <MenuItem onClick={() => this.handleClose('user')}>User Management</MenuItem> <MenuItem onClick={() => this.handleClose('user')}>Logout</MenuItem> </Menu> </div> </Toolbar> </AppBar> </div> ); } } export default withStyles(styles)(Header);
关键修改点说明
- 状态拆分:把原来单个
anchorEl拆分成listMenuAnchor和userMenuAnchor,让每个菜单拥有独立的锚点状态,避免相互干扰。 - 点击事件传参:给每个图标按钮的点击事件传入菜单类型标识,让
handleMenu能精准更新对应菜单的状态。 - 独立判断显示状态:每个菜单的
open属性基于自身的锚点状态判断,不再共用同一个变量。 - 独立关闭逻辑:关闭菜单时仅重置当前菜单的锚点状态,确保操作的独立性。
内容的提问来源于stack exchange,提问作者Glen Padua
相关产品推荐
相关产品推荐

