一. 两个时刻三个 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 属性进行区分
<2> 也可以为它们定义不同的 type
二. 异步的 state 结构
在 Web应用中,经常需要展示一些内容的列表。比如:帖子的列表、朋友的列表...首先要明确应用需要展示哪些列表,然后将他们分开存储在state中,这样才能对它们分别缓存并且在需要的时候再次请求更新数据!!
- 每个列表一般都需要使用
isFetching来显示进度条,didInvalidate来标记数据是否过期,lastUpdated来存放数据最后更新的时间,可能还需要fetchedPageCount和nextpageUrl来进行分页的相关管理。
三. 异步 action 创建函数
<1>如何把之前定义的同步 action 创建函数和网路请求结合起来呢?
标准的做法是使用Redux Thunk中间件。要引入
redux-thunk这个专门的库才可以,然后使用其中的middleware,可以使 action 创建函数除了返回 action 对象,还可以返回函数,此时,该 action 创建函数就成为了 thunk。
action 创建函数返回的函数,会被 Redux Thunk Middlewa 执行,这个函数并不需要保持纯净;它可以带有副作用,eg:执行异步的API请求,还可以 dispatch(action)
如下:
<2>关于上面请求数据所使用的 fetch():
- 使用时需要从
cross_fetch库中引入一下
<3>如何使用 Redux Middleware中间插件呢?
-
使用的是
thunkMiddleware和applyMiddleware() 插件- applyMiddleware(),参数是若干个中间插件,作用是把这些插件组合在一起,作为参数传入 createStore() 函数使用!!! -
在 createStore() 方法中实现
<4>Thunk middleware不是唯一的处理异步 action 的方式,下面有多种方式:
四. 异步数据流
使用了中间件进行包装了的 store 的dispatch()方法,可以dispatch 一些除了 action 以外的其他内容,eg: 函数或者 Promise,所使用的 middleware 会以自己的方式解析我们 dispatch 的内容,并继续传递 actions 给下一个 middleware。
注意:
- 当
middleware 链中的最后一个 middleware 开始 dispatch(action) 时,这个 action 必须是一个普通对象。这是同步式 Redux数据流开始的地方,可以使用任意多的 middleware 去做你想做的事情,但是需要使用普通对象作为最后一个被 dispatch 的action,来处理流程,并将数据流带回同步方式!!!