2024-04-22 04:44:01
Thunk 函数是 Redux 中处理异步逻辑的核心机制,Redux Toolkit 提供了 createAsyncThunk 来简化其创建过程。
Thunk 是执行延迟工作的代码部分,在 Redux 中专门用于处理异步操作(如 API 调用)。Redux 核心本身只处理同步操作,Thunk 函数通过接收 dispatch 和 getState 参数来扩展功能:
const getAllUsers = () => { return async (dispatch, getState) => { dispatch(fetchingAllUsers()); try { const users = await getUsers(); dispatch(userUpdated(users)); } catch (err) { dispatch(logError(err)); } };};Redux Toolkit 的 createAsyncThunk 是创建标准化 Thunk 的推荐方式:
import { createAsyncThunk } from '@reduxjs/toolkit';export const fetchUserById = createAsyncThunk( 'user/fetchUserById', async (userId) => { const user = await someHttpRequest(userId); return user; });参数说明createAsyncThunk 会自动生成三种状态的动作:
通过 extraReducers 字段可以处理 Thunk 的不同状态:
import { createSlice } from '@reduxjs/toolkit';const initialState = { user: null, status: 'idle', // 'idle' | 'pending' | 'succeeded' | 'failed' error: null,};export const userSlice = createSlice({ name: 'user', initialState, reducers: { // 同步reducer... }, extraReducers: (builder) => { builder .addCase(fetchUserById.pending, (state) => { state.status = 'pending'; }) .addCase(fetchUserById.fulfilled, (state, action) => { state.status = 'succeeded'; state.user = action.payload; }) .addCase(fetchUserById.rejected, (state, action) => { state.status = 'failed'; state.error = action.error.message || 'Something went wrong.'; }); },});通过第三个参数可以添加执行条件,防止重复请求:
export const fetchUserById = createAsyncThunk( "user/fetchUserById", async (userId) => { const response = await someHttpRequest(userId); return response; }, { condition(_, { getState }) { const status = selectStatus(getState()); if (status !== "idle") { return false; // 阻止Thunk执行 } }, });通过这种方式创建的 Thunk 函数能够清晰地管理异步操作的生命周期,使状态变化可预测且易于维护。