javascript - ReactJS - setState() 没有立即反映变化
问题描述
我的代码如下:
import React, { Component } from 'react';
class Counter extends Component {
constructor() {
super();
this.state = {
counter : 0
}
}
increment() {
const { counter } = this.state;
this.setState({counter : counter+1 });
console.log(counter);
}
render() {
const { counter} = this.state;
return (
<div>
<h1> {counter} </h1>
<button onClick={() => this.increment()}>Click Me</button>
</div>
);
}
}
export default Counter;
我有一个简单的 h1 和一个按钮。程序的行为应该是,当我单击按钮时,计数器的值应该增加 1(在网页和控制台上,因为我也在控制台中打印计数器的值)。问题是,当我单击按钮时,我的网页上的值从 0 变为 1,但在我的控制台中,我仍然看到计数器的值为 0(而不是 1),当我第二次单击按钮时,值从在我的网页上从 1 变为 2,但在我的控制台中,值从 0 变为 1(而不是 2)。有人可以告诉我发生了什么吗?
解决方案
setState 操作是异步的,并且为了提高性能而进行批处理。这在setState 的文档中进行了解释。
setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。在调用此方法后访问 this.state 可能会返回现有值。无法保证对 setState 的调用同步操作,并且可能会批处理调用以提高性能。
您可以使用 setState 回调来查找即时更改,也可以使用componentDidUpdate
this.setState({ counter : counter+1 }, newState => {
console.log(newState.counter)
});
或者
componentDidUpdate(prevProps, prevState) {
console.log(this.state) // New State
console.log(prevState) // Previous State
if (this.state.counter !== prevState.counter) {
// counter changed
}
}
推荐阅读
- javascript - 循环和渲染来自 3 级深度对象数组的数据
- laravel - 如何在 laravel 中创建种子层次结构
- java - 错误 java.lang.NoClassDefFoundError:Java 11 中的 javax/jws/WebService
- laravel - Laravel 调度程序在 tmp 文件夹中创建数千个日志文件
- html - HTML - “&”在评估过程中丢失
- algorithm - 为什么AA树做运算是先倾斜再分裂?
- jenkins - Jenkins 声明性管道阻塞作业
- elasticsearch - 启动 node_data 时 Elasticsearch node_master 变为离线
- css - 如何使共享类名的两个 CSS 元素不同?
- coldfusion - Cold Fusion 2018:如何将 .xlsx 文件另存为 .csv