使用Immer+Redux更新React状态时持续出现non-serializable错误
解决Redux中non-serializable值的警告问题
警告原因
控制台弹出的核心问题是:你dispatch的LOGIN action里,user.email是一个input DOM元素,而Redux要求action的payload必须是可序列化的值(比如字符串、数字、普通对象等),DOM元素无法被序列化,因此触发警告。
具体修复步骤
1. 修复mapDispatchToProps的参数传递错误
你的mapDispatchToProps中,loginRequest没有接收组件传入的邮箱和密码参数,导致调用时无法传递正确的输入值,反而可能引用了外部的DOM元素。修改为:
const mapDispatchToProps = (dispatch) => ({ login: (email, password) => dispatch(login(email, password)), logout: () => dispatch(logout()), displayNotificationDrawer: () => dispatch(displayNotificationDrawer()), hideNotificationDrawer: () => dispatch(hideNotificationDrawer()), // 新增参数接收,确保输入值能传递到action creator loginRequest: (email, password) => dispatch(loginRequest(email, password)) });
2. 确保Login组件传递输入框的值而非DOM元素
检查你的Login组件,调用logIn时必须传入输入框的value,而不是input元素本身。示例写法:
// Login组件参考实现 class Login extends Component { handleLoginSubmit = (e) => { e.preventDefault(); // 获取输入框的文本值 const email = this.emailInput.value; const password = this.passwordInput.value; // 传递值而非DOM元素 this.props.logIn(email, password); } render() { return ( <form onSubmit={this.handleLoginSubmit}> <input type="email" ref={el => this.emailInput = el} placeholder="输入邮箱" /> <input type="password" ref={el => this.passwordInput = el} placeholder="输入密码" /> <button type="submit">登录</button> </form> ); } }
3. 修正Immer reducer的写法
你当前的reducer使用Immer时存在错误:produce回调不需要return,直接修改draft即可;且不应把整个action合并到state,只需要更新user部分:
const actionsReducers = (state = {}, action) => { switch(action.type) { case LOGIN: return produce(state, (draft) => { // 直接修改draft对象,不需要return draft.user = action.user; }); default: return state; } };
4. 修复configureStore的配置错误
Redux Toolkit的configureStore默认已经集成了thunk中间件,无需手动添加;同时要使用合并后的根reducer:
const rootReducers = combineReducers({ uiReducer, actionsReducers // 注意这里是你的业务reducer名称,替换之前的笔误「reducers」 }); // 简化configureStore配置 const store = configureStore({ reducer: rootReducers });
验证效果
修改完成后,dispatch的LOGIN action会符合你的预期格式:
{ type: 'LOGIN', user: { email: 'test@test', password: 1234 } }
此时action的payload都是可序列化的字符串,控制台的non-serializable警告会消失。
内容的提问来源于stack exchange,提问作者Moez Ben Rebah
相关产品推荐
相关产品推荐

