情景描述
- 通常我们会发送一个异步请求,等到处理结果回来,选择弹出成功或者失败的气泡提示框
- 我们期望将展示部分的处理(比如弹出气泡提示框)放在组件中完成,将数据部分的处理放在reducer或者action文件中完成
- 但是不同的ui展示依赖于请求数据部分的结果,因此要将这两个部分分离开来,还要之间能够进行通信
- 以前处理这种问题的手法是:
- 将请求的结果传入store中
- 页面可以通过this.props.**访问到请求相关信息
- 然后利用componentWillReceiveProps或者render的一旦props变化就被触发的特性。每次更新显示内容。
- 上面解决方式并没有任何问题,可是我们更倾向于将会被经常使用的数据存放在store中,类似于这种可能就是一个小的功能甚至只有这一个小组件才会用到的数据放在store中可能有点大材小用了,那么有没有更好的方式呢?
解决方案
使用promise实现
- Q1:如何使用Promise实现呢?
- A1:我们可以在action的工厂函数中发送请求。
- 然后让这个action的工厂函数返回这个请求的promise
- 通常会在组件内部调用this.props.dispatchFunction
const mapDispatchToProps = (dispatch)=>{ dispatchFunction: () => dispatch(actionCreator()) }
- 函数返回值正好是这个promise直接then即可
this.props.dispatchFunction() .then(()=>{ // 实现 })
- Q2:那么按照上面的写法,dispatch的返回值是Promise吗?明明this.props.function1()的返回值是Dispatch的返回值和actionCreator()的返回值有什么关系呢?
- A2: 在这里因为我的项目中使用了bindActionCreators,因此所有类似dispatchFunction的函数其返回值都是dispatch(actionCreator())的返回值。
- 因此重点要保证dispatch的返回值一定要是promise对象,否则根本没有办法调用then。
-
Q3:那么actionCreator的返回值,对dispatch返回的promise有什么影响呢?
-
A3:actionCreator()的返回值在没有特殊情况下应该有两种类型:函数和对象
- 因此为了能很好的区别不同返回值actionCreator的promise类型,我们需要更好的了解promise对象
Promise 有两个内置属性,[[PromiseStatus]] 和 [[PromiseValue]]。
- [[PromiseStatus]]:Promise 对象的状态,这个属性可以为三个值:resolved、pending 和 rejected。(状态只能从pedding到剩下两种)
- [[PromiseStatus]]:是 Promise 的值,这个值为传入 resolve() 方法和 reject() 方法中的参数。
- actionCreator函数返回函数
- 取决于actionCreator函数返回的函数的返回值
- 返回promise:那么在组件中调用的this.props.dispatchFunction()之后的then就是被这个promise调用的
- 返回的不是promise:那么那么在组件中调用的this.props.dispatchFunction()的返回值就是undefined不能使用链式then调用
- 取决于actionCreator函数返回的函数的返回值
- actionCreator函数返回对象(仅仅取决于这个action对象的接受者)
- 直接发送到reducer的对象
- 返回的是dispatch出去的对象:那么那么在组件中调用的this.props.dispatchFunction()的返回值就是action对象不能使用链式then调用
- 发送到中间件的对象
- 这就完全取决于你中间件返回的是什么了
- promise:中间件返回的promise就是你this.props.dispatchFunction()返回的promise
- 不是promise:当然不能链式调用咯
- 这就完全取决于你中间件返回的是什么了
- 直接发送到reducer的对象
总结:dispatch异步action和使用中间件都是redux中解决异步问题的方案,但是对于使用这两种方案的mapDispatchToProps的函数的返回值我们却从未留意过,经过这一次的分许,mapDispatchToProps的函数的返回值分别是异步action的返回值和中间件函数的返回值,这对于promise的使用有很大的帮助。
- Q4:dispatch的返回值到底是不是promise呢?? 如果是状态dispatch这个promise的状态会在什么时间改变呢?
- A4:首先一定可以保证的是dispatch一定就是promise,这个promise的状态只会在当前被dispacth出去的action(同步或者异步)被某个部分接收之后才会变化,某个部分包括reducer或者中间件
网友评论