React总结篇之七_Redux和服务器通信

  • React组件访问服务器的方式
  • Redux架构下访问服务器的方式

一、React组件访问服务器

  1. 代理功能访问API
    React总结篇之七_Redux和服务器通信

  2. React组件访问服务器的生命周期

以显示天气预报为示例:

  • 通过服务器API获得天气情况数据
  • 展示天气情况数据

分两个步骤完成:
(1)在装载过程中,因为weather组件并没有获得服务器结果,就不显示结果。或者显示一个’正在装载‘之类的提示信息,但weather组件这时候要发出对服务器的请求。
(2)获取到天气数据之后,显示出来

在装载过程中,通常我们在组件的componentDidMount函数中做请求服务器的事情。

  1. React组件访问服务器的优缺点
    将状态放在组件中不是很好的选择,尤其是当组件变得复杂庞大了之后。Redux是用来帮助管理应用状态的,应该尽量把状态存放在Redux Store的状态中,而不是放在React组件中。

二、Redux访问服务器

  1. Redux-thunk中间件
    使用Redux访问服务器,同样要解决的是异步问题。
    Redux的单向数据流是同步操作,驱动Redux流程的是action对象,每一个action对象被派发到Store上之后,同步的被分配给所有的reducer函数,每个reducer都是纯函数,纯函数不产生任何副作用,自然是完成数据操作之后立刻同步返回,reducer返回的结果又被同步的拿去更新Store上的状态数据,更新状态数据的操作会立即被同步给监听Store状态改变的函数,从而引发作为视图的React组件更新过程。
    在这个过程中,Redux-chunk可以作为Redux中异步操作的方法之一。
    按照Redux-chunk的想法,在Redux的单向数据流中,在action对象被reducer函数处理之前,是插入异步功能的时机。
    在Redux架构下,一个action对象在通过store.dispatch派发,在调用reducer函数之前,会先经过一个中间件环节,这就是产生异步操作的时机,实际上Redux-chunk提供的就是一个Redux中间件,我们需要在创建store时用上这个中间件。
    React总结篇之七_Redux和服务器通信

  2. 异步action对象
    当我们想要让Redux帮忙处理一个异步操作的时候,代码一样也要派发一个action对象,毕竟Redux单向数据流就是由action对象驱动的,但是这个引发异步操作的action对象比较特殊,我们叫他们’异步action对象‘。
    有了redux-chunk中间件之后,这些action对象根本没有机会触及到reducer函数,在中间件一层就被redux-chunk截获。
    redux-chunk的工作是检查action对象是不是函数,如果不是函数就放行,完成普通action对象的生命周期,而如果发现action对象是函数,那就执行这个函数,并把Store的dispatch函数和getState函数作为参数传递到函数中去,处理过程到此为止,不会让这个异步action对象继续往前派发到reducer函数。

  3. 异步操作的模式
    一个访问服务器的action,至少要涉及3个action类型:

    • 表示异步操作已经开始的action类型,例如:表示一个请求天气信息的API请求已经发送给服务器的状态;
    • 表是异步操作成功的action类型,请求天气信息的API调用获得了正确的结果,就会引发这种类型的action;
    • 表示异步操作失败的action类型,请求天气信息的API调用任何一个环节出了错误,无论是网络错误、本地代理服务错误还是远程服务器返回的结果错误,都会引发这个类型的action。
      当这三种类型的action对象被派发时,会让React组件进入各自不同的三种状态,如:
    • 异步操作正在进行中
    • 异步操作已经成功完成
    • 任务操作已经失败
  4. 异步操作的终止
    拿天气预报的例子举例:
    从用户角度出发,当连续选择城市的时候,总是希望显示最后一次选中的城市信息,也就是说,一个更好的办法是在发出API请求的时候,将之前的API请求全部终止作废,这样就保证了获得的有效结果绝对是用户的最后一次选择结果。

三、如何挑选异步操作方式

  1. 在Redux的单向数据流中,什么时机插入异步操作?
    Redux的数据流转完全靠action来驱动,对于redux-chunk,切入异步操作的时机是在中间件中,但这并不是唯一的位置。
    通过定制化Store Enhancer,可以在action派发路径上任何一个位置插入异步操作,甚至作为纯函数的reducer都可以帮助实现异步操作。异步操作本身就是一种副作用,reducer的执行过程当然不应该产生异步操作,但是reducer函数的返回值却可以包含对异步操作的’指示‘,也就是说,reducer返回的结果可以用纯数据的方式表示需要发起一个对服务器资源的访问,由reducer调用者去真正执行这个访问服务器资源的操作,这样不违背reducer是一个纯函数的原则。

  2. 对应库的大小如何?
    几KB-几十KB

  3. 学习曲线是不是太陡?
    如果一个应用只有一个简单的API请求,使用redux-thunk能解决的话就使用redux-thunk。

  4. 是否会和其他的Redux库冲突?
    可能会发生冲突,使用任何一个库在Redux中实现异步操作,都需要多方面的考虑。

四、利用Promise实现异步操作
对于Promise在Redux库中如何实现,相关的库也很多,但是都很简单,用一个Redux中间件就可以实现:

  • redux-promise
  • redux-promises
  • redux-simple-promise
  • redux-promise-middleware