TS结合Redux Slices开发出现Cannot assign to read only property 'dis'报错如何解决
问题根因
你遇到的报错是因为 Redux Toolkit 内置的 Immer 会自动冻结所有从 store 导出的状态对象,禁止在 reducer 之外直接修改状态。你在 dataSetter 函数中直接对 params.data.dis 赋值,这里的 params.data 本质是从 Redux 取到的只读冻结对象,直接修改就会触发只读属性报错。
你硬编码数据时不会报错,是因为硬编码生成的普通对象没有被冻结,允许直接修改。
修复方案
- 第一步:在 slice 中新增用于修改单行数据的 reducer 方法
// loadSchedulerSlice.ts export const loadSchedulerSlice = createSlice({ name: 'load_scheduler', initialState, reducers: { updateGridData: (state, action: PayloadAction<DataRow>) => { let newData = [{...action.payload}] return {...state, gridData:newData} }, // 新增修改指定行dis字段的方法 updateRowDis: (state, action: PayloadAction<{id: number, newDis: string}>) => { if (!state.gridData) return const targetRow = state.gridData.find(row => row.id === action.payload.id) if (targetRow) { // Immer 允许直接修改 draft 状态 targetRow.dis = action.payload.newDis } }, }, }); // 导出新的action export const {updateGridData, updateRowDis} = loadSchedulerSlice.actions;
- 第二步:修改组件中的
dataSetter逻辑,不要直接修改行数据,改为触发 Redux action 更新状态
// LoadScheduler.ts const dataSetter = (params: { newValue: any; data: any; }) => { dispatch(updateRowDis({ id: params.data.id, newDis: params.newValue })) // 返回true告知ag-grid数据已由外部手动更新,无需内部修改 return true; };
- 补充说明:你已经开启了ag-grid的
immutableData={true}配置,当Redux中的gridData更新后,ag-grid会自动识别数据变更刷新对应行的渲染,不需要额外做同步操作。任何场景下都不要直接修改从Redux store中查询到的状态,所有状态变更都必须通过触发action走reducer流程处理。
内容的提问来源于stack exchange,提问作者Nahmed39
相关产品推荐
相关产品推荐

