setState的理解和用法


1.setState更新状态的两种写法:

 (1). setState(stateChange, [callback])------对象式的setState 1.stateChange为状态改变对象(该对象可以体现出状态的更改) 2.callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用 (2). setState(updater, [callback])------函数式的setState 1.updater为返回stateChange对象的函数。 2.updater可以接收到state和props。 4.callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。 总结: 1.对象式的setState是函数式的setState的简写方式(语法糖) 2.使用原则: (1).如果新状态不依赖于原状态 ===> 使用对象方式 例如: this.setState({msg:"我是修改后的值"}) (2).如果新状态依赖于原状态 ===> 使用函数方式 this.setState(state => ({count:state.count+1})) (3).如果需要在setState()执行后获取最新的状态数据, 要在第二个callback函数中读取

2.setState 是同步更新还是异步更新

setState 并不是单纯同步/异步的,它的表现会因调用的场景不同而不同:在React钩子函数及合成事件中,它表现为异步;而在setTimeOut,setInterval等函数中,包括在DOM原生事件中,它都表现为同步。这种差异,本质上是由React事务机制和批量更新机制的工作方式来决定的。

 

在源码中通过isBatchingUpdates 来判断setState是先存进state队列还是直接更新,如果值为true则执行异步操作,为false则直接更新。

那什么情况下 isBatchingUpdates 会为 true 呢?

· 在 React 可以控制的地方,isBatchingUpdates就为 true,比如在 React 生命周期事件和合成事件中,都会走合并操作,延迟更新的策略。

· 在 React 无法控制的地方,比如原生事件,具体就是在 addEventListener 、setTimeout、setInterval 等事件中,就只能同步更新。

 

一般认为,做异步设计是为了性能优化、减少渲染次数,React 团队还补充了两点:

· 保持内部一致性。如果将 state 改为同步更新,那尽管 state 的更新是同步的,但是 props不是。 · 启用并发更新,完成异步渲染。

 

3.如何将同步获取setState处理过后的值呢?

1)可以在回调函数中获取setState处理过后的值。

 add = ()=>{ // this.setState(state => ({count:state.count+1}))
        this.setState((preState)=>{ return {count:++preState.count} },()=>{//此时setState异步执行
            console.log(this.state.count)//1
 }) }

 

2) 可以使用es6中的async await 来实现同步。

 add = async ()=>{ await this.setState(state => ({count:state.count+1})) console.log(this.state.count)//1
    }

 

3)可以使用setTimeout、setInterval

 add =  ()=>{ setTimeout(()=>{ this.setState(state => ({count:state.count+1})) console.log(this.state.count)//1
        },0) }

 

注意:如果强行使用同步,就会每次改变状态都会重新render渲染,这样性能就会降低。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM