create-react-app的redux范例,createAsyncThunk异步函数
发布于 作者:苏南大叔 来源:程序如此灵动~
还是接着分析create-react-app的redux例子,正常的reducer定义在slice里面。但是,涉及到异步的函数,都定义到slice外面了。本文描述的就是涉及到异步的这类函数功能,相关的函数是createAsyncThunk。

大家好,这里是苏南大叔的程序如此灵动博客,写苏南大叔想写的内容。本文中,苏南大叔想写点有关redux中关于异步的处理函数的部分。如果讲的不对,欢迎留言。测试环境:win10,node@16.14.2,create-react-app@5.0.1,reduxjs/toolkit@1.8.3,react-redux@8.0.2,chrome@103.0.5060.53,redux-devtools-extension@3.0.11。
前文提要
苏南大叔先初始化了一个redux模版的react项目,然后对它进行了代码简化。相关文章:
然后,主要分析了slice.js中,如何定义reducer。参考文章:
但是,如果试图在createSlice()中的reducers字段中,定义async或者await之类的字样的话,会发生各种错误提示。那么,官方的说法是:做个切片thunk。苏南大叔对于范例中的代码再次进行了修改简化。
src/logic/slice.js:
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
function fetchCount(amount = 1) {
return new Promise((resolve, reject) =>{
const axios = require('axios');
axios.get("http://127.0.0.1:3222/hello?n="+amount).then(res => {
resolve({ data: res.data });
})
.catch(err => {});
});
}
export const c = createSlice({
name: 'counter_slice_name',
initialState :{
value: 0,
status: 'idle',
},
reducers: {
incrementByAmount: (state, action) => {
state.value += action.payload;
}
},
});
export default c.reducer;
export const { incrementByAmount } = c.actions;
export const selectCount = (state) => state.store_reducer_name.value; //解耦做的不咋地...留后患...
export const incrementAsync = createAsyncThunk(
'counter/fetchCount',
async (amount,action) => {
const response = await fetchCount(amount);
action.dispatch(incrementByAmount(response.data));
// return response.data;
}
);有关其中的异步请求的部分,请参考:

src/view/counter.js:
import { useSelector, useDispatch } from 'react-redux';
import {incrementAsync, selectCount} from './../logic/slice';
export function Counter() {
const count = useSelector(selectCount);
const dispatch = useDispatch();
return (
<div>
<span>{count}</span>
<button onClick={() => dispatch(incrementAsync(5))}>
Add Async
</button>
</div>
);
}createAsyncThunk函数定义
这个函数和原版的函数不一样,主要是对于请求得到的结果,原版的是return到addcase流程里面了,苏南大叔修改的是转入dispatch流程里面。
export const incrementAsync = createAsyncThunk(
'counter/fetchCount',
async (amount,action) => {
const response = await fetchCount(amount);
action.dispatch(incrementByAmount(response.data));
// return response.data;
}
);- 在
async函数里面,自动传入的第二个参数,它里面的dispatch可以调用其它的reducer。这也是为什么苏南大叔能够修改函数逻辑的原因。 - 这个函数的
type,是自定义的。而以前已经分析的相关type都是自动生成的。所以,在redux-devtools里面体现会有所不同。 - 因为这个
type是自定义的异步切片函数,redux-devtools自动监控到了两个异步相关的特殊type。

这里的逻辑走向,一般来说有两种。一种是直接return,那么将会走向hook里面的fulfilled逻辑。另外一种是调用action.dispatch(),直接执行相关参数。
action.dispatch(incrementByAmount(response.data));return response.data;dispatch调用
使用createAsyncThunk定义的函数,仍然是使用dispatch来调用的,和其它函数并没有区别。所以,这里就不详细说明了。可以参考文章:

onClick={() => dispatch(incrementAsync(5))}相关文章
- https://newsn.net/say/create-react-app-redux.html
- https://newsn.net/say/redux-slice.html
- https://newsn.net/say/redux-useselector.html
- https://newsn.net/say/redux-usedispatch.html
综述
苏南大叔是这么理解的,在slice外部使用createAsyncThunk处理异步,得到结果之后再dispath或者return回reducer,修改state。也就是说必须里应外合,才能处理完整个逻辑。当然了,如果并不需要得到异步返回值的话,那么异步过程直接定义在slice里面也是可以的,使用async的匿名自执行函数即可。
更多redux的经验文章,请参考下面的链接地址: