Redux Toolkit:如何使用extra builder处理多个API请求?
在Redux Toolkit同一个Slice中处理多个API请求的实现方法
刚接触Redux Toolkit的话,同一个Slice里处理多个API请求其实很直观——每个API请求对应一个由createAsyncThunk生成的异步Action,然后在extraReducers里通过builder.addCase逐个处理每个异步Action的pending/fulfilled/rejected状态即可。
具体步骤与示例代码
1. 先创建多个异步Thunk函数
每个API请求对应一个独立的createAsyncThunk,用来封装API调用逻辑:
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; import axios from 'axios'; // 异步Thunk1:获取用户列表 export const fetchUsers = createAsyncThunk('users/fetchUsers', async () => { const res = await axios.get('/api/users'); return res.data; }); // 异步Thunk2:获取单个用户详情 export const fetchUserById = createAsyncThunk('users/fetchUserById', async (userId) => { const res = await axios.get(`/api/users/${userId}`); return res.data; }); // 异步Thunk3:创建新用户 export const createUser = createAsyncThunk('users/createUser', async (userData) => { const res = await axios.post('/api/users', userData); return res.data; });
2. 在Slice的extraReducers中处理每个Thunk的状态
通过builder链式调用addCase,分别处理每个异步Thunk的三种状态:
const usersSlice = createSlice({ name: 'users', initialState: { userList: [], currentUser: null, isLoading: false, errorMsg: null, }, reducers: { // 这里放同步Action,比如清空选中用户 clearCurrentUser: (state) => { state.currentUser = null; }, }, extraReducers: (builder) => { // 处理fetchUsers的状态 builder .addCase(fetchUsers.pending, (state) => { state.isLoading = true; state.errorMsg = null; }) .addCase(fetchUsers.fulfilled, (state, action) => { state.isLoading = false; state.userList = action.payload; }) .addCase(fetchUsers.rejected, (state, action) => { state.isLoading = false; state.errorMsg = action.error.message || '获取用户列表失败'; }) // 处理fetchUserById的状态 .addCase(fetchUserById.pending, (state) => { state.isLoading = true; state.errorMsg = null; }) .addCase(fetchUserById.fulfilled, (state, action) => { state.isLoading = false; state.currentUser = action.payload; }) .addCase(fetchUserById.rejected, (state, action) => { state.isLoading = false; state.errorMsg = action.error.message || '获取用户详情失败'; }) // 处理createUser的状态 .addCase(createUser.pending, (state) => { state.isLoading = true; state.errorMsg = null; }) .addCase(createUser.fulfilled, (state, action) => { state.isLoading = false; state.userList.push(action.payload); // 创建成功后更新列表 }) .addCase(createUser.rejected, (state, action) => { state.isLoading = false; state.errorMsg = action.error.message || '创建用户失败'; }); }, }); // 导出同步Action和Reducer export const { clearCurrentUser } = usersSlice.actions; export default usersSlice.reducer;
额外优化技巧
如果多个请求的状态处理逻辑重复(比如所有请求的pending状态都是设置isLoading=true),可以抽成复用函数减少冗余:
const handlePending = (state) => { state.isLoading = true; state.errorMsg = null; }; const handleRejected = (state, action, defaultMsg) => { state.isLoading = false; state.errorMsg = action.error.message || defaultMsg; }; // 复用示例 builder .addCase(fetchUsers.pending, handlePending) .addCase(fetchUsers.rejected, (state, action) => handleRejected(state, action, '获取用户列表失败'));
内容的提问来源于stack exchange,提问作者Muhammad Awais Kayani
相关产品推荐
相关产品推荐

