React-table-v7+Redux模态框多次弹出致黑背景问题求助
问题描述
使用React-table-v7 + Redux开发带删除/编辑功能的表格时,点击打开删除模态框出现两个问题:
- 模态框重复弹出,表格有多少行就弹出多少次
- 页面出现黑背景叠加效果
核心原因
- 模态框重复实例化:在React-table的列定义中,每一行的Cell都直接渲染了
<DeleteModal />组件,表格有N行就会生成N个模态框实例。当Redux的isOpen状态变为true时,所有实例同时显示,造成重复弹出和多层黑背景。 - 全局状态无区分性:当前modal slice的
isOpen是单一布尔值,无法区分触发删除的目标行,也无法控制单个模态框的显示逻辑。
修复方案
1. 全局只保留一个模态框实例
将<DeleteModal />从表格Cell中移除,放在表格组件的外部(如页面根容器、表格容器同级),确保整页只有一个模态框实例。
2. 更新Redux状态,增加待删除行标识
修改modal slice,添加currentRowId字段记录当前要删除的行ID,实现精准控制:
// 模态框Slice修改后 const modalSlice = createSlice({ name: 'modal', initialState: { isOpen: false, currentRowId: null // 新增:存储待删除行ID }, reducers: { openModal: (state, action) => { state.isOpen = true; state.currentRowId = action.payload; // 传入点击行的ID }, closeModal: (state) => { state.isOpen = false; state.currentRowId = null; } } }); export const { reducer } = modalSlice; export default modalSlice.actions;
3. 修改表格列定义,仅渲染删除按钮
在删除列中只渲染删除图标,点击时调用Redux的openModal并传递当前行ID:
// useTableHook.js 修改后 import { useDispatch } from 'react-redux'; import { openModal } from './modalSlice'; const useTableHook = () => { const dispatch = useDispatch(); const resourcesColumns = useMemo(() => [ { Header: 'delete', accessor: () => 'delete', disableSortBy: true, Cell: ({ row }) => ( <div onClick={(event) => event.stopPropagation()}> <i className="fa fa-trash-can text-primary ZoomIcon" onClick={() => dispatch(openModal(row.id))} // 传递当前行ID /> </div> ) } ], [resourceData, dispatch]); // 添加dispatch到依赖数组 // ... 其他原有逻辑 };
4. 调整模态框组件,直接从Redux获取状态
修改DeleteModal,内部通过useSelector获取状态,无需外部传入show属性:
// 模态框视图修改后 import { useDispatch, useSelector } from 'react-redux'; import { closeModal } from './modalSlice'; const DeleteModal = () => { const dispatch = useDispatch(); const { isOpen, currentRowId } = useSelector(state => state.modal); const handlers = { closed: () => dispatch(closeModal()), confirmDelete: () => { // 这里可根据currentRowId执行删除逻辑,比如调用API或Redux action dispatch(closeModal()); } }; return ( <> <Modal show={isOpen} onHide={handlers.closed} className="modalPosition"> <Modal.Header closeButton> <Modal.Title>Atención !!</Modal.Title> </Modal.Header> <Modal.Body>Confirme que desea eliminar el recurso </Modal.Body> <Modal.Footer className="modalFooter"> <Button variant="light" onClick={handlers.closed} autoFocus={true}>Close</Button> <Button variant="primary" onClick={handlers.confirmDelete} autoFocus={true}> <i className="fa fa-check" aria-hidden="true"></i>Confirmar </Button> </Modal.Footer> </Modal> </> ); }; export default DeleteModal;
5. 在表格页面中渲染单个模态框
在tableView.jsx的合适位置(如表格外部)渲染一次模态框:
// tableView.jsx 修改后 import DeleteModal from './DeleteModal'; const TableView = () => { // ... 原有表格逻辑 return ( <div className="table-wrapper"> {/* 表格内容 */} <table> <tbody {...getTableBodyProps()}> {/* ... 原有行渲染逻辑 */} </tbody> </table> {/* 全局唯一的模态框 */} <DeleteModal /> </div> ); };
6. 清理冗余代码
- 删除Cell中原有
<DeleteModal />渲染代码 - 移除冗余的
useDeletehook,模态框内部直接从Redux获取状态
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

