# setState 详解
# 异步更新
setState
用来更新 state 进而触发 re-render 更新视图.可是它是异步更新, 意思是我调用setState
后, this.state
并没有随即发生变化:
我在handleClick
里连续三次使用了setState
结果它只更新了一次.要理解这种现象, 要先改变对setState
的理解, 要把它看作 请求(request) 而非立即更新组件的命令. 当调用setState
后会发起更新请求, React 对请求进行批处理(batch), 换句话说, 更新请求会先被搁置, 也许过一会儿又有几个更新请求过来.就像下面的小朋友们一样排队等候.然后 React 再一起处理.
对于传入对象参数的调用方式, React 会将后面的对象会覆盖之前的对象, 这等价于:
var newObj = Object.assign(
{},
{ name: "jobs", age: 12 },
{ name: "jobs", age: 12 }
);
console.log(newObj); // {name: 'jobs', age: 12}
2
3
4
5
6
7
因此, 连续三次调用this.setState({ n: this.state.n + 1 });
只会被合并成一次this.setState({ n: this.state.n + 1 });
, 所以在控制台里看到更新的n
是1
.
# 什么时候更新 state
既然不能立即更新state
,那么什么时候会呢? 我通过打 log 的方法在各个生命周期里发现state
在render 函数里更新了. 但是当shouldComponentUpdate
返回的是false
时,state
仍然会更新.
# 为何要异步更新
有以下两点原因:
目前 React 会将 setState 的效果放在队列中, 积攒着一次引发更新过程, 为的就是把 Virtual DOM 和 DOM 树操作降到最小, 用于提高性能.
shouldComponentUpdate
需要用this.state
来保留更新前的状态.一旦setState
改为同步更新,shouldComponentUpdate
也就废掉了.
# 传入函数的setState
不多逼逼, 先上代码:
这下, state
就一下子累加到3
了, React 通过函数的方式, 用参数state
进行累加, 保证了下次调用setState
时的参数state
已经更新(注意: this.state
并没有更新), 最后将参数state
更新到this.state
上. 这太牛逼了.