理解setState的关键
- setState不会立刻改变React组件中state的值;
- setState通过引发一次组件的更新过程来引发重新绘制;
- 多次setState函数调用产生的效果会合并。
这几个关键点其实是相互关联的,一个一个说吧。
需要用一个函数去更改状态,这个函数就是setState,当setState被调用时,能驱动组件的更新过程,引发componentDidUpdate、render等一系列函数的调用
调用this.setState时,并没有立即更改this.state,所以this.setState只是在反复设置同一个值而已
setState调用引起的React的更新生命周期函数4个函数(比修改prop引发的生命周期少一个componentWillReceiveProps函数),这4个函数依次被调用。
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
当shouldComponentUpdate函数被调用的时候,this.state没有得到更新。
当componentWillUpdate函数被调用的时候,this.state依然没有得到更新。
直到render函数被调用的时候,this.state才得到更新。
连续调用了两次this.setState,但是只会引发一次更新生命周期,不是两次,因为React会将多个this.setState产生的修改放在一个队列里,缓一缓,攒在一起,觉得差不多了再引发一次更新过程。
在每次更新过程中,会把积攒的setState结果合并,做一个merge的动作,所以上面的代码相当于这样。
function increment(state, props) {
return {count: state.count + 1};
}
function incrementMultiple() {
this.setState(increment);
this.setState(increment);
this.setState(increment);
}
对于多次调用函数式setState的情况,React会保证调用每次increment时,state都已经合并了之前的状态修改结果
简单说,加入当前this.state.count的值是0,第一次调用this.setState(increment),传给increment的state参数是0,第二调用时,state参数是1,第三次调用是,参数是2,最终incrementMultiple的效果,真的就是让this.state.count变成了3,这个函数incrementMultiple终于实至名归。
值得一提的是,在increment函数被调用时,this.state并没有被改变,依然,要等到render函数被重新执行时(或者shouldComponentUpdate函数返回false之后)才被改变
传统式setState的存在,会把函数式setState拖下水啊!只要有一个传统式的setState调用,就把其他函数式setState调用给害了