You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MUI Menu点击时出现黑色阴影问题求助

MUI Drawer中评论菜单点击后出现深色阴影的解决方案

我在测试用MUI Drawer展示页面评论内容时,点击评论右侧的Menu按钮,会看到按钮周围出现深色阴影。当页面只有1条评论时显示正常,多条评论时就会出现这个问题。

menu with shadow

问题原因

你推测的方向完全正确——问题出在给每条评论都渲染了一个<Menu>组件。所有Menu都绑定了同一个anchorElUser状态和open状态,当点击任意一个评论的Menu按钮时,所有评论对应的Menu都会尝试打开,多个Menu的背景/阴影层叠加,就会出现视觉上的深色阴影。

解决方案:只渲染一个全局Menu,而非每条评论都渲染

核心思路是把Menu从评论循环中抽离,只保留一个实例,同时记录当前操作的评论标识,确保编辑/删除能定位到目标评论。

修改后的代码示例:

export default function PageComments() {
  const [anchorElUser, setAnchorElUser] = useState(null);
  const [activeCommentId, setActiveCommentId] = useState(null); // 记录当前操作的评论ID
  const open = Boolean(anchorElUser);

  const toggleDrawer = (anchor, open) => (event) => {
    if (event.type === "keydown" && event.key === "Tab") {
      return;
    }
    setState({ ...state, [anchor]: open });
  };

  // 点击Menu按钮时,记录触发元素和当前评论ID
  const handleOpenUserMenu = (event, commentId) => {
    setAnchorElUser(event.currentTarget);
    setActiveCommentId(commentId);
  };

  const handleCloseUserMenu = () => {
    setAnchorElUser(null);
    setActiveCommentId(null);
  };

  // 编辑评论逻辑,通过activeCommentId定位目标
  const handleEditComment = () => {
    console.log("编辑评论:", activeCommentId);
    handleCloseUserMenu();
  };

  // 删除评论逻辑
  const handleDeleteComment = () => {
    console.log("删除评论:", activeCommentId);
    handleCloseUserMenu();
  };

  return (
    <div>
      {["right"].map((anchor) => (
        <React.Fragment key={anchor}>
          <Drawer
            anchor={anchor}
            open={state[anchor]}
            onClose={toggleDrawer(anchor, false)}
          >
            <Box
              sx={{ width: { xs: "300px", md: "450px" } }}
              role="presentation"
            >
              <div className="app">Responses({commentsWithDetails.length})</div>
              <Divider />
              {commentsWithDetails.map((comment, i) => {
                return (
                  <div className="comment" key={i}>
                    <Stack
                      spacing={1}
                      direction="row"
                      padding="5px"
                      display="flex"
                      justifyContent="space-between"
                    >
                      <div
                        style={{
                          display: "flex",
                          alignItems: "center",
                          flexWrap: "wrap",
                        }}
                      >
                        <PersonRoundedIcon sx={{ color: "#1e8e3e" }} />
                        <Stack sx={{ marginLeft: "2px" }}>
                          <span className="comment-author">
                            {comment.commentedBy}
                          </span>
                          <span className="time">
                            {comment.formattedCreateDate}
                          </span>
                        </Stack>
                      </div>

                      <IconButton
                        // 点击时传递当前评论的唯一标识
                        onClick={(e) => handleOpenUserMenu(e, comment.id || i)}
                        sx={{
                          p: "1px 1px",
                          cursor: "pointer",
                          blockSize: "20px",
                          borderRadius: "5px",
                        }}
                      >
                        <MoreVertIcon sx={{ fontSize: "medium" }} />
                      </IconButton>
                    </Stack>

                    <span className="comment-text">
                      <div
                        className="c1"
                        modelValue={comment.description}
                      />
                    </span>
                  </div>
                );
              })}
              {/* Menu移到循环外部,仅渲染一次 */}
              <Menu
                sx={{
                  mt: "25px",
                }}
                id="menu-space-page"
                anchorEl={anchorElUser}
                open={open}
                onClose={handleCloseUserMenu}
                anchorOrigin={{
                  vertical: "top",
                  horizontal: "right",
                }}
                keepMounted
                transformOrigin={{
                  vertical: "top",
                  horizontal: "right",
                }}
              >
                <MenuItem onClick={handleEditComment}>
                  <Typography sx={{ fontSize: "12px" }}>
                    Edit
                  </Typography>
                </MenuItem>

                <MenuItem onClick={handleDeleteComment}>
                  <Typography sx={{ fontSize: "12px" }}>
                    Delete
                  </Typography>
                </MenuItem>
              </Menu>
            </Box>
          </Drawer>
        </React.Fragment>
      ))}
    </div>
  );
}

关键修改说明

  • 移除循环内的Menu组件,在Drawer内部仅保留一个Menu实例
  • 新增activeCommentId状态,用于标记当前操作的评论
  • 点击Menu按钮时传递评论标识,确保编辑/删除操作能精准定位目标
  • 统一管理Menu的打开/关闭状态,避免多实例叠加导致的阴影问题

内容的提问来源于stack exchange,提问作者Udayendu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:43:11