作用
更新 State
中的数据
因为 React
不允许直接更改 state
中的数据,所以引入了 setState()
方法。当调用 setState
时,会重新执行 render
函数,进而根据最新的 State
来创建 ReactElement
对象,以此实现对 DOM
的更新
这是用于更新用户界面以响应事件处理器和处理服务器数据的主要方式
用法
setState(updater, callback)
通过 this.setState()
进行调用
setState 异步更新
constructor(props) {
super(props);
this.state = {
message: "Hello World"
}
}
changeState(){
this.setState({
message: 'Hello React'
})
console.log(this.state.message) // Hello World
}
这段代码最终打印出 Hello React
证明 setState()
是异步操作,并不能立即更新 state
中的数据
优点: 可以显著提升性能
如果每次调用 setState
都进行一次更新,那么意味着 render
函数会被频繁调用,界面重新渲染,非常影响效率,所以选择获取到多个更新之后进行批量更新
缺点: 数据无法保持同步
在开发中会产生许多问题
如何获取更新后的值:
- 通过
setState()
第二个参数–回调函数获取,该回调函数会在更新后立即执行
changeState = () => {
this.setState({
message: 'Hello React'
}), () => {
console.log(this.state.message) // Hello React
}
}
但这种貌似有些麻烦,一般使用下面这种方法
- 使用
async
和await
获取
changeState = async () => {
await this.setState({
message: 'Hello React'
)
console.log(this.state.message) // Hello React
}
- 通过生命周期函数获取
componentDidUpdate(prevProps, provState, snapshot) {
console.log(this.state.message) // Hello React
}
setState 一定是异步吗?
进行如下验证:
- 在
setTimeout
中更新
changeState() {
setTimeout(() => {
this.setState({
message: 'Hello React'
});
console.log(this.state.message); // Hello React
}, 0);
}
但是这种方法在 setTimeout
外部还是无法获取更新后的 state
的值
- 原生事件中更新
componentDidMount() {
const btn = document.getElementById("btn");
btn.addEventListener('click', () => {
this.setState({
message: 'Hello React'
});
console.log(this.state.message); // Hello React
})
}
这种方法可以在任何地方获取更新后的 state
的值
通过验证,发现 setState
并不是一定异步的
分为两种情况:
- 在组件生命周期或
React
合成事件中,setState
是异步 - 在
setTimeout
或者原生DOM
事件中,setState
是同步