React函数中等待setState完成后执行后续代码的方案咨询
解决React类组件中setState异步导致后续逻辑提前执行的问题
嘿,这个问题在React类组件里太常见了!因为setState本身是异步批量更新的,它不会立刻修改组件的state,而是把更新任务放进队列,等当前事件循环的同步代码执行完后再处理。这就导致你写在setState后面的console.log('done2')总是先于回调里的done1执行。
要实现done1先输出、done2后输出的预期效果,有两种靠谱的方案:
方案一:把后续逻辑放进setState的回调函数
setState的第二个参数就是专门用来处理状态更新完成后的逻辑的,所有需要等待状态更新完成再执行的代码,直接塞进这个回调里就行:
_toggleIsCollapsed = () => { const { isBlocked } = this.state; if (isBlocked) { console.log('blocked'); } this.setState( prevState => ({ isCollapsed: !prevState.isCollapsed }), () => { console.log('isCollapsed: ' + this.state.isCollapsed); console.log('done1'); // 把done2移到回调内,确保在状态更新完成后执行 console.log('done2'); } ); };
方案二:用Promise封装setState,结合async/await
如果你的后续逻辑比较复杂,或者不想把所有代码都塞进回调函数里,可以把setState包装成一个Promise,这样就能用async/await来优雅地等待状态更新完成:
// 先封装一个支持Promise的setState方法 setStateAsync = (updater) => { return new Promise(resolve => { this.setState(updater, resolve); }); }; _toggleIsCollapsed = async () => { const { isBlocked } = this.state; if (isBlocked) { console.log('blocked'); } // 等待状态更新完成 await this.setStateAsync(prevState => ({ isCollapsed: !prevState.isCollapsed })); console.log('isCollapsed: ' + this.state.isCollapsed); console.log('done1'); console.log('done2'); };
这两种方案都能完美解决你的问题,选哪种取决于你的代码复杂度和个人习惯~
内容的提问来源于stack exchange,提问作者Juan P. Ortiz
相关产品推荐
相关产品推荐

