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
相关产品推荐
相关产品推荐

