如何在映射的MUI表格中根据用户项单独禁用MenuItem?
问题根源与解决方案
你遇到的问题是所有行的Menu共用了同一组全局状态变量(比如anchorEl、openActionMenu),导致打开任意用户的Menu时,disabled判断逻辑会意外复用其他用户的user数据,最终出现“只要一个用户是disabled,所有MenuItem都禁用”的情况。
解决步骤:
- 将每个用户的Menu状态独立存储,避免全局状态串用
- 给每个按钮、Menu设置唯一ID,符合ARIA规范的同时避免冲突
修改后的代码示例:
首先在组件内定义独立的Menu状态:
import { useState } from 'react'; // 其他必要导入... const YourComponent = () => { // 用对象存储每个用户的Menu状态,key为用户唯一标识(优先用user.id,不用index) const [menuStates, setMenuStates] = useState({}); // 打开Menu时,记录当前用户的锚点元素和打开状态 const handleActionButtonClick = (event, userId) => { setMenuStates(prev => ({ ...prev, [userId]: { anchorEl: event.currentTarget, open: true } })); }; // 关闭Menu时,更新对应用户的状态 const handleActionMenuClose = (userId) => { setMenuStates(prev => ({ ...prev, [userId]: { ...prev[userId], open: false } })); }; // 其他组件逻辑... return ( {/* 表格容器部分 */} {users.map((user) => { // 获取当前用户的Menu状态,默认关闭状态 const currentMenu = menuStates[user.id] || { open: false, anchorEl: null }; return ( <TableRow key={user.id}> {/* 优先用user.id作为key,避免index带来的渲染异常 */} {/* 其他表格列内容... */} <TableCell> <Box> <PlainButton id={`userActionsButton-${user.id}`} {/* 每个按钮设置唯一ID */} aria-controls={currentMenu.open ? `basic-menu-${user.id}` : undefined} aria-haspopup='true' aria-expanded={currentMenu.open ? 'true' : undefined} onClick={(e) => handleActionButtonClick(e, user.id)} > Actions<ExpandMoreIcon/> </PlainButton> </Box> <Menu id={`basic-menu-${user.id}`} {/* 每个Menu设置唯一ID */} anchorEl={currentMenu.anchorEl} open={currentMenu.open} onClose={() => handleActionMenuClose(user.id)} MenuListProps={{'aria-labelledby': `userActionsButton-${user.id}`}} > <MenuItem onClick={handleOpenPasswordModal} disabled={user.userType === 'disabled'} > Option to disable </MenuItem> {/* 其他MenuItem内容... */} </Menu> </TableCell> </TableRow> ); })} ); };
关键说明:
- 用
user.id作为状态对象的key和元素ID,确保每个用户的Menu状态完全独立,不会互相干扰 - 点击按钮时,仅更新当前用户的Menu状态;关闭Menu时,也仅修改对应用户的状态
disabled判断依然直接使用当前循环的user.userType,此时每个Menu的判断逻辑只关联当前行的用户数据,不会再出现全局串用的问题
内容的提问来源于stack exchange,提问作者pivpiv
相关产品推荐
相关产品推荐

