React中setState后链式调用函数报错:Cannot read property 'then' of undefined
解决React中
TypeError: Cannot read property 'then' of undefined的问题 首先咱们拆解下你遇到的问题,一步步捋清楚出错的根源:
错误核心原因
this.setState()不返回Promise:这是触发报错的直接原因。React的setState方法本身并没有返回Promise对象,所以你试图链式调用.then()时,自然会得到“Cannot read property 'then' of undefined”的错误。- 函数被立即执行而非传递回调:就算
setState返回Promise,你当前写法里的service.logout(this.state.token)和this.Auth.logout()是直接执行了函数,而不是把函数作为回调传递给.then()——这会导致这些函数在setState还没完成时就被调用,完全达不到你想要的“依次执行”的效果。 componentWillMount已被废弃:额外提一句,React 16.3+之后官方已经不推荐使用componentWillMount了,建议改用componentDidMount(类组件场景),因为前者在服务器渲染等场景下可能出现重复执行的问题。
修复后的代码
我们可以利用setState的第二个参数(回调函数,会在状态更新完成后执行),再结合异步逻辑的处理方式,来实现你想要的流程:
方案1:如果service.logout是异步函数(返回Promise)
componentDidMount() { if (!this.Auth.loggedIn()) { this.props.history.replace('/login'); } else { const token = this.Auth.getToken(); // 先更新state,状态更新完成后执行回调 this.setState({ token }, async () => { // 等待service.logout执行完成 await service.logout(this.state.token); // 再执行Auth.logout this.Auth.logout(); }); } }
方案2:如果service.logout是同步函数
componentDidMount() { if (!this.Auth.loggedIn()) { this.props.history.replace('/login'); } else { const token = this.Auth.getToken(); this.setState({ token }, () => { service.logout(this.state.token); this.Auth.logout(); }); } }
额外说明
- 提前把
token存在变量里,是因为this.Auth.getToken()是同步获取的,这样可以避免在setState回调里重复调用;当然你直接在回调里用this.state.token也没问题,因为回调是在状态更新后执行的,能拿到最新值。 - 如果你的项目已经升级到React 18,类组件的生命周期依然可用,但新组件更推荐用函数组件+
useEffect来实现类似逻辑。
内容的提问来源于stack exchange,提问作者LogaKrishnan
相关产品推荐
相关产品推荐

