与服务器通信
与服务器通信的时长不可控,需要采用异步的形式,可以使用js的fetch函数来调用api。
fetch函数
fetch函数的基本使用形式为:
fetch(apiUrl).then((response) => {
if (response.status !== 200) {
throw new Error('Fail to get response with status ' + response.status);
}
response.json().then((responseJson) => {
this.setState(...);
}).catch((error) => {
this.setState(...);
});
}).catch((error) => {
this.setState(...);
});
以纯react(没有引入redux)的代码为例,fetch函数执行时会立即返回一个Promise类型的对象,所以要接then和catch,只要服务器返回的是合法的HTTP响应(包括500、400),都会触发then调用,所以在then回调函数中还需要判断status是否为200。
此外,即使在response.status为200时,也不能直接读取response中的内容,因为fetch在接收到HTTP响应的报头部分就会调用then,而不是等到整个HTTP响应完成。所以为了获取到body,还需要继续调用json()并针对其返回的Promise提供回调函数。
在终于成功获取到服务器返回的内容后,通过触发状态的变化引发页面的重新渲染。
redux-thunk中间件
redux的单向数据流是同步操作,如何实现调用服务器这样的异步操作呢?可以使用redux-thunk中间件。
npm install --save redux-thunk
在Redux架构下,一个action对象在通过store.dispatch派发,在调用reducer函数之前,会先经过一个中间件的环节,这就是产生异步操作的机会。
要产生异步操作要发送异步action对象,与普通的action对象不同,它并没有type字段,而且它是一个函数。而redux-thunk的工作是检查action对象是不是函数,如果不是函数就放行,完成普通action对象的生命周期,而如果发现action对象是函数,那就执行这个函数,并把Store的dispatch函数和getState函数作为参数传递到函数中去,处理过程到此为止,不会让这个异步action对象继续往前派发到reducer函数。
createStore时,将redux-thunk中间件作为storeEnhancer之一传入:
const middlewares = [thunkMiddleware];
const storeEnhancers = compose(
applyMi