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

redux中对于异步函数的处理,是使用createAsyncThunk定义的。苏南大叔也说了,要是想修改state,还是需要在slice里面做个reducer接应,里应外合才能修改数据。上一篇文章中,苏南大叔是使用dispatch来执行内应函数的。实际上,redux官方推荐里面,并不是用这种方式来对接的,而是定义了钩子函数,对异步的状态进行监控。

苏南大叔:create-react-app的redux范例,createAsyncThunk与addcase - redux-addcase
create-react-app的redux范例,createAsyncThunk与addcase(图4-1)

大家好,这里是苏南大叔的平行空间笔记本博客,这里记录苏南大叔的代码故事。本文描述slice内的addCase的概念,看看redux是如何通过addCase勾住异步请求的三个状态的。测试环境: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

官方范例定义

在上一篇文章中,苏南大叔对这个createAsyncThunk相关逻辑进行了魔改。具体参考:

本文中将把魔改的部分回滚一些,

  • 增加了slice内的extraReducersbuilder.addCase()部分。
  • createAsyncThunk中没有使用dispatch,而是使用了return
  • fetchCount内中,增加了reject()的调用。

原理上是这样的:

  • addCase实际上就是钩子的挂载点,它根据action定义或者action.type进行区分。
  • 异步操作,会产生三种状态。三种状态的区分,是通过修改type来进行区分的。

苏南大叔:create-react-app的redux范例,createAsyncThunk与addcase - 三种状态变化
create-react-app的redux范例,createAsyncThunk与addcase(图4-2)

addCase

核心代码中,通过builder.addCase()这个链式调用,来添加三种状态的state处理方式。

  • 短暂的必然存在的状态就是.pending,这个比较好理解。
  • 大多数时候,都是处理请求成功状态.fulfilled的,返回值通过action.payload来体现。
  • 个别时候,是处理异常请求状态.rejected的,其中的message是可以自定义的。
注意:createAsyncThunk()需要适时的return,而不是dispatch()
export const c = createSlice({
  //...
  extraReducers: (builder) => {
    builder
      .addCase(incrementAsync.pending, (state) => {
        state.status = 'loading';
      })
      .addCase(incrementAsync.fulfilled, (state, action) => {
        state.status = 'idle';
        state.value += action.payload;
      })
      .addCase(incrementAsync.rejected, (state, action) => {
        state.status = 'reject';
        state.error = action.error.message;
      });
  },
});

苏南大叔:create-react-app的redux范例,createAsyncThunk与addcase - 三种状态变化钩子
create-react-app的redux范例,createAsyncThunk与addcase(图4-3)

因为addCase()的第一个参数,可以表述为函数本身,也可以表述为字符串。所以,当对同一个asyncThunkAction添加钩子的时候,会报错。比如:"counter/fetchCount/pending"和“incrementAsync.pending”实际上一个效果,会报错。

值得特殊说明的是:
addCase()可以添加三种状态的钩子。但是,不能添加普通无状态的钩子。对于asyncThunkAction来说,下面的钩子是用于不会执行的。但是,如果是普通的action,确是可以执行的。

.addCase(action_type, (state) => {
  //...
})

createAsyncThunk

因为有上一篇文章的讲解,这里就着重说以下几点。如果发生异常的话,

  • 通过reject(err.message)来触发的。
  • 如果没有定义钩子的话,这里createAsyncThunk()里面就需要一个try()catch(e){}
  • 如果定义了钩子,就不需要try()catch(e){}了,会自动转到.rejected流程,并且接收action.error.message

苏南大叔:create-react-app的redux范例,createAsyncThunk与addcase - 真正的type来自这里
create-react-app的redux范例,createAsyncThunk与addcase(图4-4)

export 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 => {
      reject(err.message);
    });
  });
}
export const incrementAsync = createAsyncThunk(
  'counter/fetchCount',
  async (amount,action) => {
    const response = await fetchCount(amount);
    // action.dispatch(incrementByAmount(response.data));
    return response.data;
  }
);

注意,这个地方是return,而不是dispatch

相关文章

综述

对于create-react-appredux模版来说,到本文为止,主要的核心内容都讲完了。但是redux的其它内容,还有很多没有讲述。这些将会在后续文章里面补充。

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

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

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

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