当前位置: 首页 > 面试题库 >

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

林俊英
2023-03-14
问题内容

好的,我会尽快解决这个问题,因为它应该很容易解决…

我读过很多类似的问题,答案似乎非常明显。首先,我不需要查找任何内容!但是…我有一个错误,我无法理解如何修复或为什么会发生。

如下:

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; 如果开始为假,即使我未选中该复选框,在我第一次单击时它仍为假!!

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


问题答案:

原因是
setState是异步statesetState,如果要使用callback方法检查值,则不能紧随在之后的更新值。传递一个方法作为回调,该方法将在setState完成其任务后执行。

为什么setState是异步的?

这是因为setState更改state并导致重新渲染。这可能是一项昂贵的操作,并且synchronous可能会使浏览器无响应。因此,可以对setState调用进行asynchronous批处理,以提高UI体验和性能。

从 文档

setState()不会立即使this.state突变,而是创建一个挂起的状态转换。调用此方法后访问this.state可能会返回现有值。无法保证对setState的调用的同步操作,并且可能为提高性能而对调用进行批处理。

将回调方法与setState一起使用:

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

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'/>


 类似资料:
  • 好吧,我会尽快解决的,因为这应该是一个很容易的解决办法... 我读过一堆类似的问题,答案似乎相当明显。从一开始我就不用抬头看了!但是...我有一个错误,我无法理解如何修复或为什么它会发生。 具体如下:

  • 问题内容: 我正在阅读reactjs文档的Forms部分,只是尝试了这段代码来演示用法(JSBIN)。 在浏览器中更新值时,回调内的第二个与第一个相同,为什么在回调范围内看不到结果? 问题答案: 从React的文档中: 不会立即变异,但会创建待处理的状态转换。调用此方法后进行访问可能会返回现有值。无法保证对呼叫的同步操作,并且可以为提高性能而对呼叫进行批量处理。 如果要在状态更改发生后执行某个函数

  • 问题内容: 我正在阅读reactjs文档的Forms部分,只是尝试了这段代码来演示用法(JSBIN)。 onChange 当我在浏览器中更新值时,回调内的第二个与第一个相同,为什么在回调范围内看不到结果? 问题答案: 从React的文档中: 不会立即变异,但会创建待处理的状态转换。调用此方法后进行访问可能会返回现有值。无法保证对呼叫的同步操作,并且可以为提高性能而对呼叫进行批量处理。 如果要在状态

  • 我正在阅读 reactjs 文档的 Forms 部分,并尝试使用此代码来演示 用法 (JSBIN)。 当我更新

  • 我想问一下,为什么在执行事件时,我的状态没有改变。我已经搜索到需要在构造函数中绑定函数,但是状态仍然没有更新。 下面是我的代码:

  • 问题内容: 我想问为什么在执行onclick事件时状态没有变化。我已经搜索了一段时间,我需要在构造函数中绑定onclick函数,但状态仍未更新。这是我的代码: 问题答案: 这个回调真的很混乱。只需使用async await代替: