为什么React中调用setState后this.state没有实时更新?
原因说明
setState属于异步批量更新接口,调用后不会立刻修改当前同步作用域中的this.state。状态更新会先进入React的待更新队列,等到当前事件循环内的所有同步代码执行完毕后,React才会合并所有更新、触发组件重渲染,重渲染完成后this.state才会被更新为最新值,所以你在setState后直接打印拿不到新值。你的
setStateupdater写法存在规范错误:updater函数接收的prev参数本身就是上一次的最新状态,不需要再读取this.state,同时不允许直接修改prev对象,需要返回一个全新的状态对象,正确写法如下:
this.setState(prev => { return { isLoggedIn: !prev.isLoggedIn } })
解决方案
如果需要在状态更新完成后执行逻辑,可以使用setState的第二个参数(回调函数),该回调会在状态更新、重渲染完成后触发,此时可以拿到最新的this.state:
OnClick(){ this.setState( prev => ({ isLoggedIn: !prev.isLoggedIn }), () => { console.log(`After setState value: ${this.state.isLoggedIn}`) // 此处打印为最新值 } ) }
执行流程说明
你观察到的打印顺序完全符合React的更新逻辑:
- 点击按钮触发OnClick事件,先执行
setState将更新推入队列,this.state此时还是旧值false - 执行
setState后的同步打印语句,输出旧值false - 当前同步代码全部执行完毕,React开始处理更新队列,更新
this.state为true后触发App组件重渲染 - 进入render函数,打印更新后的状态值
true,同时将最新状态传递给Login组件,按钮文案更新为「Log Out」
内容的提问来源于stack exchange,提问作者Datadump
相关产品推荐
相关产品推荐

