在反应类组件中,为啥在按钮单击的第一个实例中状态没有改变?但在第二种情况下,它会更新吗?
Posted
技术标签:
【中文标题】在反应类组件中,为啥在按钮单击的第一个实例中状态没有改变?但在第二种情况下,它会更新吗?【英文标题】:In react class component why is the state not being changed in the first instance of button click? But in the second instance it gets updated?在反应类组件中,为什么在按钮单击的第一个实例中状态没有改变?但在第二种情况下,它会更新吗? 【发布时间】:2019-07-26 08:02:12 【问题描述】:在下面的代码中,当我第一次单击按钮时,即使使用 setState() 更改了状态,它也会打印原始状态值。但是当我第二次单击该按钮时,它会打印新的状态值
import React, Component from 'react';
class App extends Component
state =
name:'Aneesh',
age: '30'
handleClick= (event)=>
//this prints the original state
console.log(this.state);
this.setState(
name:'Rayancha'
)
//This prints the original state in the first click and prints the new state after the second click
console.log(this.state);
render()
return (
<div>
<h1>I am app component</h1>
<p>My name is: this.state.name and my Age is this.state.age</p>
<button onClick=this.handleClick>Click Me</button>
</div>
)
export default App;
【问题讨论】:
setState
是一个异步函数,详见documentation
感谢接受 algoboy :)!希望我的解决方案对您有用。
【参考方案1】:
setState
以异步方式工作。这意味着在调用 setState 之后,this.state
变量不会立即更改。因此,如果您想在状态变量上设置状态后立即执行操作,然后返回结果,请使用回调。
尝试使用回调函数如下:
handleClick= (event)=>
//this prints the original state
console.log(this.state);
this.setState(
name:'Rayancha'
, () => console.log(this.state))
这将确保在返回setState
时调用console.log。
【讨论】:
此外,如果您可以使用 async/await,您可以将箭头函数标记为async
和 await
setState
。后续代码只会在状态更新后运行。
@Phillip 这不是真的,因为setState
不会返回Promise
(你不能await
它)。【参考方案2】:
您的代码实际上正在正确更新。问题是在调用this.setState()
之后直接执行console.log(this.state)
。你看,this.setState()
是异步的,这意味着当你调用它时,没有什么可以阻止在它之后编写的代码立即运行。简单地说,console.log()
在状态更新完成之前运行。
作为您的状态实际更新的证据,您可以在render
中运行console.log()
。因为,每次更新状态时组件都会re-render
,因此您将打印新的状态值。
import React, Component from 'react';
class App extends Component
state =
name:'Aneesh',
age: '30'
handleClick= (event)=>
//this prints the original state
console.log(this.state);
this.setState(
name:'Rayancha'
)
//This prints the original state in the first click and prints the new state after the second click
console.log(this.state);
render()
console.log(this.state.name)
return (
<div>
<h1>I am app component</h1>
<p>My name is: this.state.name and my Age is this.state.age</p>
<button onClick=this.handleClick>Click Me</button>
</div>
)
export default App;
【讨论】:
【参考方案3】:你做得对,控制台会在你的状态设置之前执行,所以如果你把控制台放在渲染中,你可以看到你的状态已经正确改变了。
要解决此问题,您必须向 setState 传递一个回调,该回调仅在您的 setState 执行后才会执行。
如果确实需要,请使用回调,如果您想在渲染下使用状态,则必须避免这种情况,因为在多次渲染的情况下它会使您的应用程序变慢。
handleClick= (event)=>
this.setState(
name:'Rayancha'
, () => console.log(this.state))
请查看seState Api https://reactjs.org/docs/react-component.html#setstate的官方文档
【讨论】:
以上是关于在反应类组件中,为啥在按钮单击的第一个实例中状态没有改变?但在第二种情况下,它会更新吗?的主要内容,如果未能解决你的问题,请参考以下文章
Angular - 从特定组件实例获取数据,以便能够通过单击按钮与之交互