react-setState的同步与异步

setState何时同步何时异步?

在写react类组件的时候,setState是一个很好用的状态管理方法,但是用着用着,就会发现问题,比如最常见的,setState后打印,并没有打印最新的状态,这可是好家伙,看了官方文档发现,想获得最新的状态,可以在setState加上第二个callback函数,如:

1
setState(newState,()=>console.log(newstate))

这样就能获得最新状态了。
在深入研究一下,setState竟然有时候是同步的,有时候是异步的!
异步的不说了,大多都是异步的情况,在settimeout,promise这些函数中使用setState他就是同步的,如:

1
2
3
4
5
setTimeout(()=>{
console.log(prestate)
setState(newState)
console.log(newstate)
},100)

学到了!
有人可能会说了,这设计真反人类,但是要清楚,将state的更新延缓到最后批量合并再去渲染对于应用的性能优化是有极大好处的,如果每次的状态改变都去重新渲染真实dom,那么它将带来巨大的性能消耗。


那么我们在研究一下这个异步是真的异步吗?
并不是的,react只是模拟了异步,看起来像而已,react为了解决跨平台,兼容性问题,自己封装了一套事件机制,代理了原生的事件,像在jsx中常见的onClick、onChange这些都是合成事件,React中维护一个标识(isBatchingUpdates),判断是直接更新还是先暂存state进队列。在setTimeout中调用以及原生事件中调用的话,是可以立马获取到最新的state的。根本原因在于,setState并不是真正意义上的异步操作

上一篇

js中的定时器