You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 14:53:11