-
setState 在生命周期和合成事件中是异步;在原生事件和异步方法里是同步;(异步方法里主要是涉及到js事件循环的宏任务和微任务。)
-
setState 异步实际上是生命周期和合成事件在更新之前被调用,导致他们拿到的数据不是更新后的值。
-
setState 在生命周期和合成事件中会进行批量更新优化,即对同一个key进行多次setState,只取最后一次执行。如果是更新多个key,在更新时合并批量更新。
合成事件、生命周期的setState
这两段代码表明在合成事件和生命周期里,setState是异步的,并且多次setState只会更新最后一个设置的值。
// 代码1
import React, { Component } from "react";
export default class App extends Component {
state = {
count: 0,
};
changeCount = () => {
console.info(this.state.count); // 0
this.setState({
count: 1,
});
this.setState({
count: 3,
});
console.info(this.state.count); // 0
};
render() {
return (
<div>
<button onClick={this.changeCount}> 点击</button>
渲染结果等于3 {this.state.count}
</div>
);
}
}
// 代码2
import React, { Component } from "react";
export default class App extends Component {
state = {
count: 0,
};
componentDidMount() {
console.info(this.state.count); // 0
this.setState({
count: 1,
});
this.setState({
count: 3,
});
console.info(this.state.count); // 0
}
render() {
return <div>渲染结果等于3 {this.state.count}</div>;
}
}
原生事件里的setState
import React, { Component } from "react";
export default class App extends Component {
state = {
count: 0,
};
changeCount = () => {
console.info(this.state.count); // 0
this.setState({
count: this.state.count + 1,
});
console.info(this.state.count); // 1
};
componentDidMount() {
document.getElementById("btn").addEventListener("click", this.changeCount);
}
render() {
return (
<div>
<button id="btn">点击{this.state.count}次</button>
</div>
);
}
}
异步函数中的setState
import React, { Component } from "react";
export default class App extends Component {
state = {
count: 0,
};
componentDidMount() {
setTimeout(() => {
console.info(this.state.count); // 0
this.setState({ count: this.state.count + 1 });
console.info(this.state.count); // 1
}, 0);
}
render() {
return <div> {this.state.count}</div>;
}
}
练习题
最后来看下,这段代码的输出结果:
import React, { Component } from "react";
export default class App extends Component {
state = {
count: 0,
};
componentDidMount() {
this.setState({ count: this.state.count + 1 });
console.log("origin1", this.state.count); // 0 step1
this.setState({ count: this.state.count + 1 });
console.log("origin2", this.state.count); // 0 step2
setTimeout(() => {
console.log("timeout start", this.state.count); // 3 step9
this.setState({ count: this.state.count + 1 });
console.log("timeout1", this.state.count); // 4 step10
this.setState({ count: this.state.count + 1 });
console.log("timeout2", this.state.count); // 5 step11
}, 1000);
new Promise((reslove) => {
console.log("Promise start", this.state.count); //0 step3
this.setState({ count: this.state.count + 1 });
console.log("Promise1", this.state.count); // 0 setp4
reslove({});
this.setState({ count: this.state.count + 1 });
console.log("Promise2", this.state.count); // 0 setp5
}).then(() => {
console.log("then", this.state.count); // 1 setp6
this.setState({ count: this.state.count + 1 });
console.log("then1", this.state.count); // 2 setp7
this.setState({ count: this.state.count + 1 });
console.log("then2", this.state.count); // 3 setp8
});
}
render() {
return <div>setState {this.state.count}</div>;
}
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!