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

Material UI:如何在ReactJS中针对单个元素仅显示一次Modal?

解决React中点击Remove按钮弹窗多次的问题

这问题我以前也碰到过,核心原因是你把Modal放在了map循环里面——每一个数组元素都对应生成了一个Modal,当你把removeImportGroup设为true时,所有Modal都会同时触发显示,自然就出现了弹窗多次的情况。

要解决这个问题,我们只需要把Modal移到循环外部,同时用一个状态记录当前要删除的元素索引即可,具体步骤如下:

具体修改方案

  1. 新增一个状态存储要删除的元素索引,用来标记当前操作的是哪一个元素
  2. 将Modal组件从map循环中移出,确保页面只有一个Modal实例
  3. 点击Remove按钮时,记录当前元素索引并打开Modal
  4. 在Modal的确认删除操作中,使用存储的索引来执行删除逻辑

修改后的完整代码

const [importedgroups, setimportedgroups] = React.useState(groups.groupsList);
const [removeImportGroup, setremoveImportGroup] = React.useState(false);
// 新增状态:存储要删除的元素索引
const [deleteIndex, setDeleteIndex] = React.useState(null);

const handleRemoveDownGroup = () => {
  setremoveImportGroup(false);
  // 关闭弹窗时重置删除索引
  setDeleteIndex(null);
};

const removeGroups = () => {
  if (deleteIndex === null) return;
  const removeg = [...importedgroups];
  removeg.splice(deleteIndex, 1);
  setimportedgroups(removeg);
  // 删除后关闭弹窗
  setremoveImportGroup(false);
  setDeleteIndex(null);
};

return (
  <>
    {/* 表格部分 */}
    { importedgroups.map((row, index) => (
      <TableRow key={row.name}>
        <TableCell>{row.groupName}</TableCell>
        <TableCell>
          <Button 
            href="#text-buttons" 
            color="primary" 
            disableRipple 
            onClick={() => {
              // 点击时记录当前索引并打开弹窗
              setDeleteIndex(index);
              setremoveImportGroup(true);
            }} 
          >
            <div>
              <RemoveCircleOutlineIcon/>{" "} Remove
            </div>
          </Button>
        </TableCell>
      </TableRow>
    )) }

    {/* Modal移到循环外部,全局只有一个 */}
    <Modal 
      className="modal__style" 
      open={removeImportGroup} 
      onClose={handleRemoveDownGroup} 
      closeAfterTransition 
      BackdropComponent={Backdrop} 
      BackdropProps={{ timeout: 500, }} 
    >
      <Fade in={removeImportGroup}>
        <div className="modal__paper">
          <h3> &nbsp;&nbsp;&nbsp;Remove </h3>
          <p > Are you sure you remove this group permanently? </p>
          <form>
            <Button variant="outlined" disableRipple onClick={handleRemoveDownGroup} > Cancel </Button>
            <Button variant="contained" disableRipple onClick={removeGroups} > Continue </Button>
          </form>
        </div>
      </Fade>
    </Modal>
  </>
);

代码说明

  • 新增的deleteIndex状态专门用来记录当前要删除的元素索引,避免了循环中多个Modal同时触发的问题
  • Modal被移到了循环外部,整个页面只有一个实例,无论数组有多少元素,点击按钮只会打开这一个弹窗
  • 点击Remove按钮时,先把当前元素的索引存到deleteIndex,再打开Modal;删除操作时直接使用这个索引来处理数组
  • 关闭弹窗或完成删除后,都会重置deleteIndex,避免后续操作出现异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 12:57:38