React useState与setState的对比分析
一、React中setState/useState执行的同步异步问题
原则:
- 只要代码进入了 react调度流程,那就是异步的。
- 只要代码没有进入 react调度流程,那就是同步的。
setTimeout、setInterval、async中await的后续部分,Promise.then(),以及直接在 DOM 上绑定原生事件等。这些都不会走 React调度流程,在这种情况下调用 setState ,那这次 setState 就是同步的。 否则就是异步的。
A.观察多次setState的渲染次数与执行时机
实验1、连续执行两个 setState
class DemoClassComp extends React.Component {
constructor(props) {
super(props)
this.state = {
a: 'a',
b: 'b',
}
}
outControl = () => {
Promise.resolve().then(() => {
this.setState({
...this.state, a: 'aa'})
this.setState({
...this.state, b: 'bb'})
})
}
inControl = () => {
this.setState({
...this.state, a: 'aa'})
this.setState({
...this.state, b: 'bb'})
}
render() {
console.log('render')
return (
<>
<button onClick={
this.inControl} >【react调度】</button>
<button onClick={
this.outControl} >【不受react调度】</button>
</>
)
}
}
实验现象:
- 当点击【react调度】按钮时,会进行batchUpdate批量更新,只会重新渲染render一次
- 当点击【不受react调度】按钮时,render 了两次
实验2、连续执行两次同一个 setState
class DemoClassComp extends React.Component {
constructor(props) {
super(props)
this.state = {
number: 0,
}
}
outControl = () => {
Promise.resolve().then(() => {
this.setState({
number: this.state.number + 1})
this.setState({
number: this.state.number + 1})
})
}
outControl2 = () => {
Promise.resolve().then(() => {
const newState = {
number: this.state.number + 1};
this.setState(newState)
this.setState(newState)
})
}
inControl = () => {
this.setState({
number: this.state.number + 1})
this.setState({
number: this.state.number + 1})
}
render() {
const {
number } = this.state;
console.log({
number});
return (
<>
<button onClick={
this.inControl} >【react调度】</button>
<button onClick={
this.inControl2} >【react调度2】<</