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

Redux reducer中使用Async/Await报错:检测到非可序列化状态值

问题根源

Redux 的 reducers 必须是纯同步函数,不能包含异步逻辑。你把 loginUser 设为 async 函数后,它会返回一个 Promise 对象,而 Redux 会把这个 Promise 当作 state 的一部分——Promise 属于非可序列化的值,因此触发了"A non-serializable value was detected"的报错。

解决方案

用 Redux Toolkit 内置的 Thunk 中间件处理异步逻辑,把异步请求从 reducer 中剥离,只让 reducer 处理同步的状态更新:

1. 修改 Auth Slice,定义同步状态更新的 reducers

const authSlice = createSlice({
  name: "auth",
  initialState: {
    value: {
      fields: initialState, // 假设这里是你的初始表单状态,比如{ email: '', password: '', loading: false }
      user: null,
      error: null
    },
  },
  reducers: {
    // 设置加载状态
    setLoading: (state, action) => {
      state.value.fields.loading = action.payload;
    },
    // 登录成功更新状态
    loginSuccess: (state, action) => {
      state.value.user = action.payload;
      state.value.error = null;
    },
    // 登录失败更新状态
    loginFailure: (state, action) => {
      state.value.error = action.payload;
      state.value.user = null;
    },
  },
});

// 导出同步action
export const { setLoading, loginSuccess, loginFailure } = authSlice.actions;

2. 创建 Thunk 函数处理异步登录请求

// 异步登录的action creator(Thunk)
export const loginUser = () => async (dispatch, getState) => {
  // 获取当前state中的邮箱和密码
  const { email, password } = getState().auth.value.fields;
  
  // 先触发加载状态
  dispatch(setLoading(true));

  try {
    const response = await http.post("/login", { email, password });
    console.log(response.data);
    // 登录成功,分发成功action
    dispatch(loginSuccess(response.data));
  } catch (err) {
    // 登录失败,分发失败action
    dispatch(loginFailure(err.message));
  } finally {
    // 无论成功失败,结束加载状态
    dispatch(setLoading(false));
  }
};

export default authSlice.reducer;

3. 在组件中使用这个 Thunk

在组件里直接调用 dispatch(loginUser()) 即可触发异步登录流程。

内容的提问来源于stack exchange,提问作者Mishen Thakshana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:25:27