为什么调用 setState 方法不会立即改变状态?



好吧,我会尽力使它快速,因为它应该很容易解决...

我已经读了很多类似的问题,答案似乎很明显。首先,我永远不必抬头!但是...我有一个错误,我无法理解如何解决或为什么会发生。

如下:

class NightlifeTypes extends Component {
constructor(props) {
    super(props);
    this.state = {
        barClubLounge: false,
        seeTheTown: true,
        eventsEntertainment: true,
        familyFriendlyOnly: false
    }
    this.handleOnChange = this.handleOnChange.bind(this);
}
handleOnChange = (event) => {   
    if(event.target.className == "barClubLounge") {
        this.setState({barClubLounge: event.target.checked});
        console.log(event.target.checked)
        console.log(this.state.barClubLounge)
    }
}
render() {
    return (
        <input className="barClubLounge" type='checkbox' onChange={this.handleOnChange} checked={this.state.barClubLounge}/>
    )
}

更多的代码包围了这一点,但这是我的问题所在。应该工作吗?

我也尝试过:

handleOnChange = (event) => {   
if(event.target.className == "barClubLounge") {
    this.setState({barClubLounge: !this.state.barClubLounge});
    console.log(event.target.checked)
    console.log(this.state.barClubLounge)
}

所以我有这两个console.log(),都应该相同。我实际上将状态设置为与上方行中的event.target.checked相同!

,但它总是返回应有的相反。

当我使用!this.state.barClubLounge时,也是如此;如果它启动false,则在我的第一次点击时,它仍然是错误的,即使检查复选框是否基于状态!

这是一个疯狂的悖论,我不知道发生了什么,请帮助!

原因是 setState是异步,如果您想检查值使用callback方法,则无法期望setState之后更新的state值。将方法传递给setState完成任务后将执行的方法。

为什么setstate是异步的?

这是因为setState改变了state并导致重新渲染。这可能是一个昂贵的操作,使其synchronous可能会使浏览器无反应。因此,setState的调用为asynchronous,并且批次以获得更好的UI体验和性能。

来自Doc

setState()不会立即突变。 等待国家过渡。访问此。 方法可能会返回现有值。没有 保证对SetState的通话和呼叫的呼叫同步操作可能 批次获得性能。

使用setState使用回调方法:

要在setState之后检查更新的state值,请使用这样的回调方法:

setState({ key: value }, () => {
     console.log('updated state value', this.state.key)
})

检查以下内容:

class NightlifeTypes extends React.Component {
   constructor(props) {
      super(props);
      this.state = {
         barClubLounge: false,
         seeTheTown: true,
         eventsEntertainment: true,
         familyFriendlyOnly: false
      }
   }
   handleOnChange = (event) => {  // Arrow function binds `this`
      let value = event.target.checked;
      if(event.target.className == "barClubLounge") {
         this.setState({ barClubLounge: value}, () => {  //here
             console.log(value);
             console.log(this.state.barClubLounge);
             //both will print same value
         });        
      }
   }
   render() {
      return (
          <input className="barClubLounge" type='checkbox' onChange={this.handleOnChange} checked={this.state.barClubLounge}/>
      )
   }
}
ReactDOM.render(<NightlifeTypes/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>

因为setState是一个异步函数。这意味着在调用SetState状态变量后不会立即更改。因此,如果要在更改状态后立即执行其他操作,则应使用SetState Update功能内的SetState回调方法。

handleOnChange = (event) => { 
     let inputState = event.target.checked;
      if(event.target.className == "barClubLounge") {
         this.setState({ barClubLounge: inputState}, () => {  //here
             console.log(this.state.barClubLounge);
             //here you can call other functions which use this state 
             variable //
         });        
      }
   }

这是由于性能考虑而逐设计的。React中的SetState是函数保证重新渲染组件,这是一个昂贵的CPU过程。因此,其设计师希望通过将多个渲染动作收集到一个方面来优化,因此SetState是异步的。

相关内容

  • 没有找到相关文章

最新更新