Material UI:如何在ReactJS中针对单个元素仅显示一次Modal?
解决React中点击Remove按钮弹窗多次的问题
这问题我以前也碰到过,核心原因是你把Modal放在了map循环里面——每一个数组元素都对应生成了一个Modal,当你把removeImportGroup设为true时,所有Modal都会同时触发显示,自然就出现了弹窗多次的情况。
要解决这个问题,我们只需要把Modal移到循环外部,同时用一个状态记录当前要删除的元素索引即可,具体步骤如下:
具体修改方案
- 新增一个状态存储要删除的元素索引,用来标记当前操作的是哪一个元素
- 将Modal组件从
map循环中移出,确保页面只有一个Modal实例 - 点击Remove按钮时,记录当前元素索引并打开Modal
- 在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> 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
相关产品推荐
相关产品推荐

