7.2.2 异步action对象
您可以在百度里搜索“深入浅出React和Redux 艾草文学(www.321553.xyz)”查找最新章节!
7.2.2 异步action对象
当我们想要让Redux帮忙处理一个异步操作的时候,代码一样也要派发一个action对象,毕竟Redux单向数据流就是由action对象驱动的。但是这个引发异步操作的action对象比较特殊,我们叫它们“异步action对象”。
前面例子中的action构造函数返回的都是一个普通的对象,这个对象包含若干字段,其中必不可少的字段是type,但是“异步action对象”不是一个普通JavaScript对象,而是一个函数。
如果没有redux-thunk中间件的存在,这样一个函数类型的action对象被派发出来会一路发送到各个reducer函数,reducer函数从这些实际上是函数的action对象上是无法获得type字段的,所以也做不了什么实质的处理。
不过,有了redux-thunk中间件之后,这些action对象根本没有机会触及到reducer函数,在中间件一层就被redux-thunk截获。
redux-thunk的工作是检查action对象是不是函数,如果不是函数就放行,完成普通action对象的生命周期,而如果发现action对象是函数,那就执行这个函数,并把Store的dispatch函数和getState函数作为参数传递到函数中去,处理过程到此为止,不会让这个异步action对象继续往前派发到reducer函数。
举一个并不涉及网络API访问的异步操作例子,在Counter组件中存在一个普通的同步增加计数的action构造函数increment,代码如下:
const increment = () => ({
type: ActionTypes.INCREMENT,
});
派发increment执行返回的action对象,Redux会同步更新Store状态和视图,但是我们现在想要创造一个功能,能够发出一个“让Counter组件在1秒之后计数加一”的指令,这就需要定义一个新的异步action构造函数,代码如下:
const incrementAsync = () => {
return (dispatch) => {
setTimeout(() => {
dispatch(increment());
}, 1000);
};
};
异步action构造函数incrementAsync返回的是一个新的函数,这样一个函数被dispatch函数派发之后,会被redux-thunk中间件执行,于是setTimeout函数就会发生作用,在1秒之后利用参数dispatch函数派发出同步action构造函数increment的结果。
这就是异步action的工作机理,这个例子虽然简单,但是可以看得出来,异步action最终还是要产生同步action派发才能对Redux系统产生影响。
redux-thunk要做的工作也就不过如此,但因为引入了一次函数执行,而且这个函数还能够访问到dispatch和getState,就给异步操作带来了可能。
action对象函数中完全可以通过fetch发起一个对服务器的异步请求,当得到服务器结果之后,通过参数dispatch,把成功或者失败的结果当做action对象再派发出去。这一次派发的是普通的action对象,就不会被redux-thunk截获,而是直接被派发到reducer,最终驱动Store上状态的改变。 深入浅出React和Redux