我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

还是接着分析create-react-appredux例子,正常的reducer定义在slice里面。但是,涉及到异步的函数,都定义到slice外面了。本文描述的就是涉及到异步的这类函数功能,相关的函数是createAsyncThunk

苏南大叔:create-react-app的redux范例,createAsyncThunk异步函数 - 切片函数
create-react-app的redux范例,createAsyncThunk异步函数(图4-1)

大家好,这里是苏南大叔的程序如此灵动博客,写苏南大叔想写的内容。本文中,苏南大叔想写点有关redux中关于异步的处理函数的部分。如果讲的不对,欢迎留言。测试环境:win10node@16.14.2create-react-app@5.0.1reduxjs/toolkit@1.8.3react-redux@8.0.2chrome@103.0.5060.53redux-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;
  }
);

有关其中的异步请求的部分,请参考:

苏南大叔:create-react-app的redux范例,createAsyncThunk异步函数 - createasyncthunk
create-react-app的redux范例,createAsyncThunk异步函数(图4-2)

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函数定义

这个函数和原版的函数不一样,主要是对于请求得到的结果,原版的是returnaddcase流程里面了,苏南大叔修改的是转入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

苏南大叔:create-react-app的redux范例,createAsyncThunk异步函数 - 特殊的type
create-react-app的redux范例,createAsyncThunk异步函数(图4-3)

这里的逻辑走向,一般来说有两种。一种是直接return,那么将会走向hook里面的fulfilled逻辑。另外一种是调用action.dispatch(),直接执行相关参数。

action.dispatch(incrementByAmount(response.data));
return response.data;

dispatch调用

使用createAsyncThunk定义的函数,仍然是使用dispatch来调用的,和其它函数并没有区别。所以,这里就不详细说明了。可以参考文章:

苏南大叔:create-react-app的redux范例,createAsyncThunk异步函数 - dispatch2
create-react-app的redux范例,createAsyncThunk异步函数(图4-4)

onClick={() => dispatch(incrementAsync(5))}

相关文章

综述

苏南大叔是这么理解的,在slice外部使用createAsyncThunk处理异步,得到结果之后再dispath或者returnreducer,修改state。也就是说必须里应外合,才能处理完整个逻辑。当然了,如果并不需要得到异步返回值的话,那么异步过程直接定义在slice里面也是可以的,使用async的匿名自执行函数即可。

更多redux的经验文章,请参考下面的链接地址:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   react    redux