都知道React的类组件在setState的时候有异步和同步的区别,但是具体哪些是同步哪些是异步?
原理在这里就不细说了,感兴趣的同学可以看看源码:源码有个inBatchUpdate的Flag,在React自身的事件流/生命周期中这个Flag是true,setState请求会放入一个队列里,在做更新的时候会进行合并。但是React自身事件流意外的时候这个Flag是false,那么setState请求会同步执行。
看下面代码
import React from 'react';
export default class SetStateTest extends React.PureComponent {
constructor(props) {
super(props);
this.state = { stateName: "init" }
this.handleSynSet = this.handleSynSet.bind(this);
this.handleDom2EventSet = this.handleDom2EventSet.bind(this);
this.handlePromiseSet = this.handlePromiseSet.bind(this);
this.handleAwaitSet = this.handleAwaitSet.bind(this);
}
handleSynSet() {
this.setState({ stateName: "synClick1" });
console.log(this.state.stateName);
this.setState({ stateName: "synClick2" });
console.log(this.state.stateName);
}
handleDom2EventSet() {
this.setState({ stateName: "domClick1" });
console.log(this.state.stateName);
this.setState({ stateName: "domClick2" });
console.log(this.state.stateName);
}
componentDidMount() {
this.setState({ stateName: "mount1" });
console.log(this.state.stateName);
this.setState({ stateName: "mount2" });
console.log(this.state.stateName);
document.getElementById("dom2Event").addEventListener("click", this.handleDom2EventSet);
}
componentWillUnmount() {
document.getElementById("dom2Event").removeEventListener("click", this.handleDom2EventSet);
}
handlePromiseSet() {
new Promise((resolve, reject) => {
this.setState({ stateName: "promise1" });
console.log(this.state.stateName);
this.setState({ stateName: "promise2" });
console.log(this.state.stateName);
return resolve("promise3");
}).then((result) => {
this.setState({ stateName: "promise4" });
console.log(this.state.stateName);
this.setState({ stateName: "promise5" });
console.log(this.state.stateName);
});
}
async handleAwaitSet() {
const awaitResult = await new Promise((resolve, reject) => resolve("await1"));
this.setState({ stateName: "await2" });
console.log(this.state.stateName);
this.setState({ stateName: "await3" });
console.log(this.state.stateName);
}
render() {
return (
<div>
<div>
<button onClick={this.handleSynSet}>Synthetic SetState</button>
<button id="dom2Event">Dom2 Event SetState</button>
<button onClick={this.handlePromiseSet}>Promise SetState</button>
<button onClick={this.handleAwaitSet}>Await SetState</button>
</div>
<div>
<span>stateName:{this.state.stateName}</span>
</div>
</div>
)
}
}
依次点击按钮,所有的console的输出结果:
init
init
mount2
mount2
domClick1
domClick2
domClick2
domClick2
promise4
promise5
await2
await3