ReactTabulator传入Redux状态数据时报错:MachineID只读
解决react-tabulator读取Redux数据时报“MachineID只读”的问题
问题核心
react-tabulator内部可能会尝试修改传入的data数组或其中的对象,但Redux store返回的数据是**不可变(只读)**的——Redux要求必须通过action修改状态,不能直接篡改store返回的对象,这就是报错的根本原因。而TanStack Table默认不会修改原始数据,所以能正常运行。
可行解决方案
1. 深度克隆Redux数据,彻底隔离只读引用
浅拷贝(比如[...data]或Object.assign)只会复制数组外层,数组内的对象还是引用Redux的只读对象,react-tabulator修改属性时仍会报错。必须做深度克隆:
// 方案1:JSON序列化/反序列化(注意:数据里有函数、Symbol等特殊类型会丢失) const clonedData = JSON.parse(JSON.stringify(reduxData)); // 方案2:用lodash深克隆(需先安装lodash) import cloneDeep from 'lodash/cloneDeep'; const clonedData = cloneDeep(reduxData);
之后把clonedData传给ReactTabulator的data属性即可。
2. 开启react-tabulator只读模式,禁止内部修改数据
如果你的表格不需要编辑功能,直接全局或针对列禁用编辑,从根源上避免它修改数据:
<ReactTabulator data={reduxData} options={{ editable: false, // 全局禁用编辑 columns: [ { title: 'Machine ID', field: 'MachineID', editable: false }, // 其他列配置 ] }} />
3. 用useMemo缓存深克隆数据,优化性能
直接在渲染阶段深克隆会导致每次重渲染都重复克隆,用useMemo缓存可以避免不必要的性能损耗:
import { useMemo } from 'react'; import { useSelector } from 'react-redux'; const MyTable = () => { const reduxData = useSelector(state => state.machines.data); const tableData = useMemo(() => { return JSON.parse(JSON.stringify(reduxData)); }, [reduxData]); // 仅当reduxData变化时才重新克隆 return ( <ReactTabulator data={tableData} columns={columns} /> ); };
验证小技巧
可以在控制台打印Object.isFrozen(reduxData[0]),如果返回true,说明对象被Redux Toolkit自动冻结了(createSlice默认会冻结状态对象,防止直接修改)。
内容的提问来源于stack exchange,提问作者Anukool
相关产品推荐
相关产品推荐

