Redxu(RTK) 基础 对thunk的补充(createAsyncThunk和extraReducers)
补充 thunk的编写模式
上个章节,我们提到了thunk。
我想了一下,有一个重点没说。
1.reducer就是用于处理数据的逻辑
2.reducer中不能放置任何异步的逻辑
基于上面两点,thunk必须存在。
但是上个视频介绍的手动编写thunk的方法还是太麻烦,
rtk提供了便捷的帮助函数,可以简化这个过程,形式如下:
注意incrementAsync 异步返回的值 就会形成payload!
export const incrementAsync = createAsyncThunk(
"counter/awaitPromise",
async (amount: number) => {
const response = await Promise.resolve({ data: 10 });
// The value we return becomes the `fulfilled` action payload
return response.data;
}
);
注意一下,这个incrementAsync可以直接被dispatch ,不用再找额外的actionCreator,redux会知晓incrementAsync是一个包含异步逻辑的函数,该函数的结果会被包装为aciton交付给redux store。
注意,构建异步thunk,需要传入具体的一个用于区分的action名字,他的格式是:slice名字/具体操作的名字。
在thunk里的第二个参数就是你的异步逻辑,现在我们一般都是用async函数来编写。
thunk像普通action一样使用。比如 dispatch(incrementAsync()。但这还不够。
因为我们还需要额外给这个thunk规定他如何处理state中对应数据,一般增加一个额外的reducer
范式如下:
extraReducers: (builder) => {
builder
.addCase(incrementTenAsync.pending, (state, action) => {
state.status = "loading";
})
.addCase(incrementTenAsync.rejected, (state, action) => {
state.status = "failed";
})
.addCase(incrementTenAsync.fulfilled, (state, action) => {
state.value += action.payload;
state.status = "idle";
});
},
extraReducer就是一个函数,他的参数是builder,builder提供了根据异步thunk不同(promise)状态添加不同数据处理逻辑的工具addCase。
addCase就很简单,能在builder上链式调用,根据thunk不同状态做对应操作。
另外,如果你非要手写thunk,看下边。
// We can also write thunks by hand, which may contain both sync and async logic.
// Here's an example of conditionally dispatching actions based on current state.
export const incrementIfOdd =
(amount: number): AppThunk =>
(dispatch, getState) => {
const currentValue = selectCount(getState());
if (currentValue % 2 === 1) {
dispatch(incrementByAmount(amount));
}
};