如何通过action动态存储键值对,解决Map不可序列化、Record不可扩展报错
问题根因
你遇到的两个报错都是Redux/NgRx类状态管理框架的典型规则限制导致的:
- 用
Record<string, number>时报「对象不可扩展」:框架默认会冻结所有状态对象防止直接修改,你直接在原状态的Record上新增键属于修改原对象,因此触发限制。 - 用
Map<string, number>时报「不可序列化状态」:框架默认要求状态必须是可序列化为JSON的纯基础结构,Map属于内置引用类型,不符合序列化要求。
正确实现方案
直接用Record<string, number>即可,只要改成immutable更新的写法,不修改原状态对象即可:
1. 状态定义保持用Record
export interface State extends EntityState<Airplane> { error?: any; aircraftRotation: Record<string, number>; } export const initialState: State = airplanesAdapter.getInitialState({ error: null, aircraftRotation: {}, // 初始为空对象即可 }); export default State;
2. Reducer写法改成返回新状态
不要修改原state的属性,而是通过展开运算符生成新的状态对象和新的aircraftRotation对象,把新键值对合并进去:
function updateAircraftRotation(state: State, aircraftCallSing: string, rotation: number): State { return { ...state, // 复制原有状态的其他属性 aircraftRotation: { ...state.aircraftRotation, // 复制原有已存的键值对 [aircraftCallSing]: rotation // 新增/覆盖本次要更新的键值对 } }; }
可选:删除键的写法
如果后续需要删除某个键,先拷贝原Record再删除,再返回新对象即可:
function deleteAircraftRotation(state: State, aircraftCallSing: string): State { const newRotation = { ...state.aircraftRotation }; delete newRotation[aircraftCallSing]; return { ...state, aircraftRotation: newRotation }; }
这个方案完全符合状态管理的immutable规则和序列化要求,性能也能满足绝大多数业务场景。
内容的提问来源于stack exchange,提问作者D.Zet
相关产品推荐
相关产品推荐

