本文将围绕setState展开以下相关知识点
-
setState的基础语法
-
setState是同步还是异步的?
-
为什么setState在react中要设计为异步的?
-
代码验证
一,setState的基础语法:
setState(updater[, callback])
第一个参数updater:函数或者对象类型;
第一个参数updater为函数时:
// 写法一
this.setState((state, props) => {
return {
counter: state.counter + props.num
}
})
// 写法二
this.setState((state, props) => ({
counter: state.counter + props.num
}))
第一个参数updater为对象类型时:
this.setState({
counter: 23
})
注意:如果后续更新的state状态要使用当前state的状态值时:
// 不建议这么写
this.setState({
counter: this.state.counter + 10
});
// 建议这么写(使用函数写法)
this.setState((state) => ({
counter: state.counter + 10
}));
第二个参数callback
// 初始化的state
this.state = {
counter: 0
};
....
// 更新counter
this.setState((state) => ({counter: state.counter + 10 }), () => {
console.log(this.state.counter);
})
那么,callback回调函数是在什么时候执行的?如下为官网提供的答案:
不熟悉的小伙伴们,以后在面试时千万别再说setState的第二个参数callback是同步执行的哦,说明你连官网都没看完
二,setState是同步的还是异步的?
1,setState并不是单纯的同步或者异步的,它的执行效果会因调用场景的不同而表现不同;
2,在合成事件及生命周期方法中表现为异步,在addEventListener、setTimeout、setInterval等原生事件中表现为同步;
3,在源码中,通过isBatchingUpdates来判断的,如果isBatchingUpdates为true,则将state状态存进state队列中进行批量合并后异步更新,如果为isBatchingUpdates为false,则执行同步更新。
三,为什么setState在react中要设计为异步的?
做异步设计是为了性能优化、减少渲染次数,React团队还补充了两点(源址):
1,保持内部一致性,确保内部状态提升是安全的。
保持state与props的一致性,如果setState改为同步方式,state得到更新,而props却不是。
2,启用并发更新
setState根据数据来源不同,分配不同的优先级来完成异步渲染。
四,代码测试验证
componentDidMount(){
this.setState({
count: this.state.count + 1
});
console.log('count11=', this.state.count);
this.setState({
count: this.state.count+ 1
});
console.log('count12=', this.state.count);
setTimeout(() => {
console.log('count20=', this.state.count);
this.setState({
count: this.state.count + 1
});
console.log('count21=', this.state.count);
this.setState({
count: this.state.count + 1
});
console.log('count22=', this.state.count);
}, 0);
}
// 执行结果如下:
count11= 0
count12= 0
count20= 1
count21= 2
count22= 3