Redux -- 异步action

455 阅读3分钟

一. 两个时刻三个 action

当调用异步 API 时,有两个非常关键的时刻:发起请求的时刻接收到响应的时刻, 这两个时刻都可能会更改应用的 state ,所以至少要 dispatch三种普通的同步 action

  • 一种通知 reducer 请求开始的 action

      - 对于这种 action ,reducer 可能会切换一下 state 中的`isFetching`标记。以此来告诉 UI 组件来显示加载页面!!!
    
  • 一种是通知 reducer 请求成功的 action

      - 对于这种 action ,reducer可能会把接收到的新数据合并到 state 中,并且重置`isFetching` 。UI组件会隐藏加载页面,并显示接收到的数据
    
  • 一种是通知 reducer 请求失败的 action

      - 对于这种 action ,reducer 可能会重置 `isFetching`。另外,有些 reducer 会保存这些失败信息,并在 UI 里显示出来。
    

<1>这三种 action 可以用相同的 type 类型命名,但在各自的 action 对象中添加一个专门的 status 属性进行区分

1813.png <2> 也可以为它们定义不同的 type

1814.png

二. 异步的 state 结构

在 Web应用中,经常需要展示一些内容的列表。比如:帖子的列表、朋友的列表...首先要明确应用需要展示哪些列表,然后将他们分开存储在state中,这样才能对它们分别缓存并且在需要的时候再次请求更新数据!!

  • 每个列表一般都需要使用isFetching来显示进度条,didInvalidate来标记数据是否过期,lastUpdated来存放数据最后更新的时间,可能还需要fetchedPageCountnextpageUrl来进行分页的相关管理。

三. 异步 action 创建函数

<1>如何把之前定义的同步 action 创建函数和网路请求结合起来呢?

标准的做法是使用Redux Thunk中间件。要引入 redux-thunk这个专门的库才可以,然后使用其中的 middleware ,可以使 action 创建函数除了返回 action 对象,还可以返回函数,此时,该 action 创建函数就成为了 thunk。

action 创建函数返回的函数,会被 Redux Thunk Middlewa 执行,这个函数并不需要保持纯净;它可以带有副作用,eg:执行异步的API请求,还可以 dispatch(action)

如下:

1815.png

<2>关于上面请求数据所使用的 fetch():

  • 使用时需要从 cross_fetch库中引入一下

<3>如何使用 Redux Middleware中间插件呢?

  • 使用的是thunkMiddlewareapplyMiddleware() 插件

    - applyMiddleware(),参数是若干个中间插件,作用是把这些插件组合在一起,作为参数传入 createStore() 函数使用!!!
    
  • 在 createStore() 方法中实现

1816.png

<4>Thunk middleware不是唯一的处理异步 action 的方式,下面有多种方式:

1817.png

四. 异步数据流

使用了中间件进行包装了的 store 的dispatch()方法,可以dispatch 一些除了 action 以外的其他内容,eg: 函数或者 Promise,所使用的 middleware 会以自己的方式解析我们 dispatch 的内容,并继续传递 actions 给下一个 middleware。

注意:

  • middleware 链中的最后一个 middleware 开始 dispatch(action) 时,这个 action 必须是一个普通对象。这是同步式 Redux数据流开始的地方可以使用任意多的 middleware 去做你想做的事情,但是需要使用普通对象作为最后一个被 dispatch 的action,来处理流程,并将数据流带回同步方式!!!