最近复习了一些关于react的基础,记录一下,setState使用的细节。
setState的异步更新
自定义事件中为异步更新
{this.state.message}
changeText() {
this.setState({
message: "Hello React"
})
console.log(this.state.message); // Hello World, 并不能同步拿到最新值 Hello React
}
为什么setState设计为异步呢?
setState设计为异步,可以显著的提升性能;
如果每次调用setState都进行一次更新,那么意味着render函数会被频繁调用,界面重新渲染,这样效率是很低的;最好的办法应该是获取到多个更新,之后进行批量更新;
如果同步更新了state,但是还没有执行render函数,那么state和props不能保持同步;state和props不能保持一致性,会在开发中产生很多的问题
及时获取到setState异步更新后的值:
1.setState(partialState, callback) 通过回调,callback方法获取,
changeText() {
this.setState({
message: "Hello React"
}, () => {
console.log(this.state.message); // Hello React
});
}
2.生命周期函数 componentDidUpdate 获取
componentDidUpdate(prevProps, provState) {
console.log(this.state.message); // Hello React
}
setState的同步更新
setTimeout 中为同步更新
changeText() {
setTimeout(() => {
this.setState({
message: "Hello React"
});
console.log(this.state.message); // Hello React
}, 0);
}
原生DOM事件中为同步更新
const btnEl = document.getElementById("btn");
btnEl.addEventListener('click', () => {
this.setState({
message: "Hello React"
});
console.log(this.state.message); // Hello React
})
setState的数据合并
使用 Object.assign(target, …sources)来完成的,每次setState并没有直接替换state中的所有数据,而是覆盖差异项,就是setState中的key项
setState的方法合并
多个setState连续执行,最终只会执行一个,例子中最后counter只增加了 1
increment() {
this.setState({
counter: this.state.counter + 1
});
this.setState({
counter: this.state.counter + 1
});
this.setState({
counter: this.state.counter + 1
});
}
setState(callback) 取消合并,例子中最后counter只增加了 3
increment() {
this.setState((state, props) => {
return {
counter: state.counter + 1
}
})
this.setState((state, props) => {
return {
counter: state.counter + 1
}
})
this.setState((state, props) => {
return {
counter: state.counter + 1
}
})
}
总结
在组件生命周期或React合成事件中,setState是异步; 在定时器或原生dom事件中,setState是同步;
setState数据合并,实际上是Object.assign(target, …sources)
通过setState(callback)的方式可取消setState的多个合并