react setstate()的秘密
setState
先看这个例子
this.state = {
count: 0,
}
incrementCount() {
this.setState({
count: this.state.count + 1,
});
}
handleIncrement = () => {
this.incrementCount();
this.incrementCount();
this.incrementCount();
}
点击一次,累加三次,但是只累加了一次
纠正:
incrementCount(){
this.setState((prev)=>{
return {count:preState.count+1}
})
}
setstate()传入参数的区别
传入obj | 传入更新函数 |
---|---|
不可以访问当前状态值 | 可以访问当前的状态值 |
setstate是batchUpdate的,因此可以使得更新建立在彼此之上,避免冲突。
setstate 为什么不会同步更新?
一些setstate的基本知识
-
setstate不会立刻改变react组件中的state值
-
setstate通过触发组件的一次更新触发重绘
-
多次setstate产生的效果会合并
重绘指的就是引发react的更新生命周期的四个函数:
-
shouldComponentUpdate 若返回false 则state依旧会更新 否则不跟新走到下一个周期
-
componentWillUpdate(state不更新)
render(this.state更新了)
-
componentDidUpdate
-
-
目前React会把setState的效果放在队列中,积攒
一次引发更新
的过程,这是一种优化,尽可能减少虚拟dom和dom操作 -
同步的办法:
由react引发的事件处理,比如通过onclick触发的事件处理,调用setState不会同步更新this.STATE。
- 主要的思路是绕过react通过addEventListener直接添加事件的处理函数,还有通过settimeout等产生的异步。
-
更新机制
:
在React的setState函数实现中,会根据一个变量 isBatchingUpdates
判断是直接更新
this.state 还是放到队列
中。
而isBatchingUpdates
默认是false
,也就表示setState会同步更新
this.state,但是有一个函数batchedUpdates
。
这个函数会把isBatchingUpdates
修改为true
,而当React在调用事件处理函数之前就会调用这个batchedUpdates
,造成的后果,就是由React控制的事件处理过程setState不会同步更新
this.state。