
redux 要求状态必须是可序列化的(即能被 json 安全表示),而 javascript 类实例因包含原型、方法和隐藏属性,违反该原则,导致“non-serializable value”警告。最佳实践是用普通对象(plain object)替代类实例来建模状态。
redux 要求状态必须是可序列化的(即能被 json 安全表示),而 javascript 类实例因包含原型、方法和隐藏属性,违反该原则,导致“non-serializable value”警告。最佳实践是用普通对象(plain object)替代类实例来建模状态。
在使用 Redux Toolkit(RTK)构建状态逻辑时,createSlice 默认启用严格的可序列化检查(通过 serializableCheck middleware)。当你将 User 类实例赋值给 state.user 时,即使类中所有字段都是字符串,其内部仍携带不可序列化的构造函数、原型链及潜在的 getter/setter 或方法——这些都会触发警告甚至在开发模式下抛出错误。
✅ 正确做法:完全放弃类,改用类型别名(Type Alias)+ 普通对象
Orderly React SDK 钩子使用参考指南,包括 useOrderEntry、usePositionStream、useOrderbookStream、useCollateral 等。
// ✅ 推荐:使用 plain object + type alias(无运行时开销,100% 可序列化)
export type User = {
name: string;
email: string;
token: string;
};
export type AccountState = {
id: string;
user?: User;
};
const initialState: AccountState = {
id: '',
};
const accountSlice = createSlice({
name: 'account',
initialState,
reducers: {
setAccount(state, action: PayloadAction<{ id: string; name: string; email: string; token: string }>) {
const { id, name, email, token } = action.payload;
state.id = id;
state.user = { name, email, token }; // ← 纯对象,无原型污染
},
},
});⚠️ 注意事项:
- 不要使用
new User(...)或任何类构造调用; - 避免在状态中存储函数、Date、RegExp、Map、Set、Promise、undefined(尤其注意
undefined在对象中可能意外出现); - 若需复用逻辑(如用户校验、格式化),应封装为纯函数(utility functions),而非类方法;
- 如业务中已存在
User类用于 API 层或领域模型,可在数据流入 Redux 前做「序列化适配」:
// 例如:从 API 响应转换为可序列化状态
const toSerializableUser = (user: User): User => ({
name: user.name,
email: user.email,
token: user.token,
});
// 在 thunk 或 RTK Query 的 `transformResponse` 中使用? 进阶建议:
若 User 和 Account 关系复杂、需独立更新或跨组件复用,可考虑拆分为 userSlice 和 accountSlice,并通过 extraReducers 或 createAsyncThunk 协同更新——但这属于状态解耦优化,并非解决不可序列化问题的必要条件。核心原则始终不变:Redux 状态树中只存放可序列化的纯数据。
总结:可序列化不是限制,而是保障时间旅行调试、持久化、服务端渲染等关键能力的基础。拥抱 plain object,让状态更轻量、更可靠、更符合 Redux 设计哲学。

















