React/Redux/Thunk中无法调用action返回Promise的.then方法问题
.then的问题 嘿,我明白你遇到的问题了!你已经成功触发了action、更新了store,但就是没法在调用this.props.add(project)之后链式调用.then,报错说undefined。这问题其实出在你的mapDispatchToProps函数里,咱们一步步理清楚:
问题根源
你的mapDispatchToProps里的add方法是这么写的:
function mapDispatchToProps(dispatch) { return { add: (project) => { dispatch(projectActions.add(project)); } }; }
这里的箭头函数用了大括号,但没有显式返回值,所以默认返回undefined。而实际上,dispatch(projectActions.add(project))是会返回一个Promise的(因为你的action creator返回的是一个异步函数,redux-thunk执行它后会返回这个函数里的Promise),但你没把这个返回值传出去,自然调用this.props.add(...)得到的就是undefined,没法调用.then。
解决方案
有三种简单的修复方式:
方式1:显式返回dispatch的结果
把箭头函数里的代码加上return,让它把dispatch的返回值(也就是Promise)传递出去:
function mapDispatchToProps(dispatch) { return { add: (project) => { return dispatch(projectActions.add(project)); } }; }
方式2:用箭头函数的隐式返回
去掉大括号,箭头函数会自动返回后面表达式的结果,写法更简洁:
function mapDispatchToProps(dispatch) { return { add: (project) => dispatch(projectActions.add(project)) }; }
方式3:使用bindActionCreators(推荐的简洁写法)
Redux提供了bindActionCreators工具函数,可以帮你自动把action creators绑定到dispatch上,并且返回的函数会正确传递Promise返回值:
import { bindActionCreators } from 'redux'; function mapDispatchToProps(dispatch) { return bindActionCreators({ add: projectActions.add }, dispatch); }
这样写之后,this.props.add就会直接是绑定好的函数,调用它会自动dispatch对应的action,同时返回Promise,你就能正常用.then了。
验证修改效果
修改之后,你的handleSubmit里的代码就能正常工作:
handleSubmit(e) { e.preventDefault(); var project = { name: this.state.projectName }; this.props.add(project).then(() => { // 这里可以写请求成功后的逻辑,比如跳转到项目列表页 }).catch(error => { // 也能直接捕获请求失败的错误信息 }); }
另外要说明的是,你的action creator和API调用代码是完全没问题的,它已经正确返回了Promise,只要mapDispatchToProps把这个Promise传递出来,就能实现链式调用了。
内容的提问来源于stack exchange,提问作者robobby

