异步模式
Redux 异步模式
- 当任何动作被派发时,执行额外的逻辑(如记录动作和状态
) 。 - 暂停、修改、延迟、替换或停止被派发的动作。
- 编写能够访问
dispatch 和getState 的额外代码。 - 教会
dispatch 如何接受除了普通动作对象以外的其他值,比如函数和Promise ,通过拦截它们并调度真正的动作对象来代替它们
- redux-thunk,让你可以直接写出可能包含异步逻辑的普通函数。
- redux-saga,它使用生成器函数来返回行为描述,以便它们可以被中间件执行。
- redux-observable,它使用
RxJS observable 库来创建处理动作的函数链。
我们推荐使用
在Slices 中定义异步逻辑
一个典型的包含
// First, define the reducer and action creators via `createSlice`
const usersSlice = createSlice({
name: "users",
initialState: {
loading: "idle",
users: [],
},
reducers: {
usersLoading(state, action) {
// Use a "state machine" approach for loading state instead of booleans
if (state.loading === "idle") {
state.loading = "pending";
}
},
usersReceived(state, action) {
if (state.loading === "pending") {
state.loading = "idle";
state.users = action.payload;
}
},
},
});
// Destructure and export the plain action creators
export const { usersLoading, usersReceived } = usersSlice.actions;
// Define a thunk that dispatches those action creators
const fetchUsers = () => async (dispatch) => {
dispatch(usersLoading());
const response = await usersAPI.fetchAll();
dispatch(usersReceived(response.data));
};
- 在请求之前,先派发一个 “start” 动作,以表明请求正在进行中。这可以用来跟踪加载状态,以允许跳过重复的请求或在
UI 中显示加载指标。 - 发出实际请求
- 根据请求结果,异步逻辑会派发一个包含结果数据的 “success” 操作,或一个包含错误详情的 “failure” 操作。在这两种情况下,
reducer 都会清除加载状态,并处理成功情况下的结果数据,或者存储错误值,以便潜在地显示。
作为开发人员,你可能最关心的是提出
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { userAPI } from "./userAPI";
// First, create the thunk
const fetchUserById = createAsyncThunk(
"users/fetchByIdStatus",
async (userId, thunkAPI) => {
const response = await userAPI.fetchById(userId);
return response.data;
}
);
// Then, handle actions in your reducers:
const usersSlice = createSlice({
name: "users",
initialState: { entities: [], loading: "idle" },
reducers: {
// standard reducer logic, with auto-generated action types per reducer
},
extraReducers: {
// Add reducers for additional action types here, and handle loading state as needed
[fetchUserById.fulfilled]: (state, action) => {
// Add user to the state array
state.entities.push(action.payload);
},
},
});
// Later, dispatch the thunk as needed in the app
dispatch(fetchUserById(123));
interface ThunkAPI {
dispatch: Function
getState: Function
extra?: any
requestId: string
signal: AbortSignal
}