
本文档旨在解决在使用 React、Redux Toolkit 和 MUI X DataGrid 时,如何有效地管理来自多个 DataGrid 组件的选中行数据。我们将探讨一种将每个 DataGrid 的选中数据存储在单独的状态中的方法,并提供详细的代码示例和步骤说明。
在使用 React 和 MUI X DataGrid 构建复杂应用时,经常会遇到需要在多个 DataGrid 组件中管理选中行数据的情况。 传统的集中式状态管理方法可能会导致代码复杂性增加,并且难以维护。本文档将介绍一种更有效的方法,即为每个 DataGrid 组件使用单独的状态,从而简化代码并提高可维护性。
问题背景
假设我们有一个包含多个 DataGrid 组件的页面,每个组件显示不同类型的数据(例如,TCG 技能、管理技能、销售技能和软技能)。每个 DataGrid 组件都有复选框,允许用户选择多行。我们需要将每个 DataGrid 组件中选中的行数据存储在单独的状态中,以便在应用程序的其他部分中使用。
解决方案
该解决方案的核心思想是为每个 DataGrid 组件创建一个单独的 Redux slice,并在每个 slice 中维护一个 selected 状态来存储选中的行数据。
1. 创建 Redux Slice
首先,为每个 DataGrid 组件创建一个 Redux slice。例如,对于 "softSkill",创建一个 softSkillSlice.js 文件:
// softSkillSlice.js
import { createSlice } from '@reduxjs/toolkit';
const softSkillSlice = createSlice({
name: 'softSkill',
initialState: {
skills: [], // 假设你的 skill 数据存储在这里
selected: [],
},
reducers: {
setSkills: (state, action) => {
state.skills = action.payload;
},
setSkillSelected: (state, action) => {
state.selected = action.payload;
},
},
});
export const { setSkills, setSkillSelected } = softSkillSlice.actions;
export default softSkillSlice.reducer;对其他 DataGrid 组件(adminSkill, tcgSkill, salesSkill)重复此步骤,并相应地调整 slice 名称和 reducer。
NetGou是一款国内知名的购物系统网店系统,它功能强大完善、运行稳定快速、界面友好人性化、可扩展性强。系统支持无限级商品分类管理、商品品牌管理、商品供货商管理、商品可同时加入多个商品分类商品批发价格,购买不同的商品数量可以设置不同的价格。不同的商品选项可以设置不同的价格订单中可以加入商品、删除商品、更改商品数量和价格、更改配送方式和配送费用新闻管理、销售统计、数据备份恢复,不同的会员等级可以设置
2. 修改 DataGrid 组件
修改 TableReusable 组件,使其接受一个 setSkillSelected prop,该 prop 是对应 Redux slice 的 setSkillSelected action。
// TableReusable.js
import React from 'react';
import { DataGrid } from '@mui/x-data-grid';
import { useDispatch } from 'react-redux';
import { useSearchBar } from '../hooks/useSearchBar';
export const TableReusable = ({ data, columns, bool, setSkillSelected }) => {
const dispatch = useDispatch();
const onRowsSelectionHandler = (ids) => {
const selectedRowsData = ids?.map((id) =>
data?.find((row) => row?._id === id || row?.id === id)
);
dispatch(setSkillSelected(selectedRowsData));
};
const filteredRows = useSearchBar({ row: data });
return (
row?.id || row?._id || row?.CommonId}
columns={columns}
initialState={{
pagination: { paginationModel: { pageSize: 10 } },
}}
onRowSelectionModelChange={(ids) => onRowsSelectionHandler(ids)}
componentsProps={{
pagination: {
labelRowsPerPage: `Nb par page`,
},
}}
pageSizeOptions={[5, 10, 15, 20, 50, 100]}
checkboxSelection={bool}
/>
);
}; 3. 修改 DataGrid 包装组件
修改包装 DataGrid 组件(例如 SoftTable、AdminTable 等),并将相应的 setSkillSelected action 作为 prop 传递给 TableReusable 组件。
// SoftTable.js
import React from 'react';
import { useSelector } from 'react-redux';
import { TableReusable } from '../../../reusable/TableReusable';
import { setSkillSelected } from '../../../slices/softSkillSlice';
export const SoftTable = () => {
const data = useSelector((state) => state?.softSkill?.skills) || [];
const columns =
data.length > 0
? Object.keys(data[0])
.filter(
(field) =>
field !== 'Level' &&
field !== 'updated_at' &&
field !== 'created_at'
)
.map((field) => ({
field: field,
headerName: field,
width: 130,
}))
: [];
return (
);
};对其他 DataGrid 包装组件重复此步骤,并传递相应的 setSkillSelected action。
4. 在父组件中使用 DataGrid 包装组件
在父组件(例如 ListSkills)中使用 DataGrid 包装组件。
// ListSkills.js
import React from 'react';
import { Box, Typography } from '@mui/material';
import { TcgTable } from '../list/TcgTable';
import { AdminTable } from '../list/AdminTable';
import { SalesTable } from '../list/SalesTable';
import { SoftTable } from '../list/SoftTable';
export const ListSkills = () => {
return (
<>
TCG Skills
ADMIN Skills
SALES skills
SOFT skills
>
);
};总结
通过为每个 DataGrid 组件创建单独的 Redux slice,我们可以有效地管理来自多个表格的选中数据。这种方法简化了代码,提高了可维护性,并使我们能够轻松地访问和使用应用程序其他部分的选中数据。
注意事项
- 确保正确配置 Redux store,并将所有 slice 添加到 reducer 中。
- 根据你的具体需求调整代码示例。
- 考虑使用 TypeScript 来提高代码的类型安全性和可读性。









