createAsyncThunk中rejectWithValue失效问题求助
问题
使用Redux Toolkit的createAsyncThunk实现React API调用时遇到异常:代码中保留rejectWithValue时thunk无法执行,移除该方法后thunk可正常运行,怀疑是thunk中间件配置错误。相关代码如下:
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; const initialState = { productList: [], Rejected: false, Pending: false, }; export const productDataApi = createAsyncThunk( "product/Card", async ({ rejectWithValue }) => { console.log("in thunk"); try { const res = await fetch(`${process.env.REACT_APP_BASE_URL}`); const result = await res.json(); console.log("result", result); return result; } catch (err) { rejectWithValue(err); } } ); const productSlice = createSlice({ name: "product", initialState, reducers: {}, extraReducers: (builder) => { builder .addCase(productDataApi.pending, (state) => { state.Pending = true; }) .addCase(productDataApi.fulfilled, (state, action) => { console.log(action.payload); state.productList = action.payload; }) .addCase(productDataApi.rejected, (state, action) => { state.Rejected = true; state.Pending = true; }); }, }); export default productSlice.reducer;
import { configureStore } from "@reduxjs/toolkit"; import productSlice, { productDataApi } from "./actions/productSlice"; const store = configureStore({ reducer: { product: productSlice, }, middleware: (getDefaultMiddleware) => { getDefaultMiddleware({ thunk: { extraArgument: { productDataApi, }, }, serializableCheck: false, }); }, }); export default store;
解决方案
1. 修正createAsyncThunk的回调参数结构
createAsyncThunk的回调函数第一个参数是调用thunk时传入的参数,第二个参数才是包含rejectWithValue的thunkAPI对象。你的代码错误地将rejectWithValue作为第一个参数解构,导致参数获取失败,直接中断thunk执行。另外,rejectWithValue需要通过return传递错误,否则无法触发rejected分支。
修复后的productDataApi代码:
export const productDataApi = createAsyncThunk( "product/Card", // 第一个参数用_标记未使用,第二个参数解构rejectWithValue async (_, { rejectWithValue }) => { console.log("in thunk"); try { const res = await fetch(`${process.env.REACT_APP_BASE_URL}`); // 补充处理HTTP错误状态码(fetch仅在网络错误时进入catch) if (!res.ok) { throw new Error(`请求失败,状态码:${res.status}`); } const result = await res.json(); console.log("result", result); return result; } catch (err) { // return错误值,传递到rejected分支 return rejectWithValue(err.message); } } );
2. 修复store的middleware配置
你的middleware函数没有返回getDefaultMiddleware的处理结果,导致默认中间件(包括thunk)未被注入store,这是thunk无法正常工作的核心原因。同时,无需将productDataApi作为extraArgument传入,属于冗余配置。
修复后的store代码:
import { configureStore } from "@reduxjs/toolkit"; import productSlice from "./actions/productSlice"; const store = configureStore({ reducer: { product: productSlice, }, middleware: (getDefaultMiddleware) => // 必须return配置后的中间件数组 getDefaultMiddleware({ serializableCheck: false, }), }); export default store;
3. 修正rejected状态的逻辑
在rejected分支中,你错误地将Pending设为true,应该改为false,保证状态一致性:
.addCase(productDataApi.rejected, (state, action) => { state.Rejected = true; state.Pending = false; // 修正为false });
完成以上三点修复后,rejectWithValue就能正常将错误传递到rejected分支,thunk也能正常执行。
内容的提问来源于stack exchange,提问作者Interview Benzatine
相关产品推荐
相关产品推荐

