为什么调用 setState 方法不会立即改变状态? [英] Why calling setState method doesn't mutate the state immediately?

查看:33
本文介绍了为什么调用 setState 方法不会立即改变状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我会尽量快点,因为它应该很容易解决...

Ok, i'll try and make this quick because it SHOULD be an easy fix...

我看过一堆类似的问题,答案似乎很明显.没有什么我首先需要查找的!但是...我遇到了一个错误,我无法理解如何修复或为什么会发生这种错误.

I've read a bunch of similar questions, and the answer seems to be quite obvious. Nothing I would ever have to look up in the first place! But... I am having an error that I cannot fathom how to fix or why its happening.

如下:

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}/>
    )
}

更多代码围绕这一点,但这就是我的问题所在.应该工作吧?

More code surrounds this but this is where my problem lies. Should work, right?

我也试过这个:

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 相同!

So I have those two console.log()'s, both should be the same. I'm literally setting the state to be the same as the event.target.checked in the line above it!

但它总是返回与它应该相反的东西.

But it always returns the opposite of what it should.

当我使用 !this.state.barClubLounge 时也是如此;如果它开始为假,在我第一次点击时它仍然为假,即使复选框是否被选中是基于状态!

Same goes for when I use !this.state.barClubLounge; If it starts false, on my first click it remains false, even though whether the checkbox is checked or not is based off of the state!!

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

It's a crazy paradox and I have no idea whats going on, please help!

推荐答案

原因是 setState 是异步的,你不能指望 state 值就在 setState,如果您想检查值,请使用 callback 方法.传递一个方法作为回调,该回调将在 setState 完成其任务后执行.

Reason is setState is asynchronous, you can't expect the updated state value just after the setState, if you want to check the value use a callback method. Pass a method as callback that will be get executed after the setState complete its task.

为什么 setState 是异步的?

Why setState is asynchronous ?

这是因为 setState 改变了 state 并导致重新渲染.这可能是一项代价高昂的操作,并且使其同步 可能会使浏览器无响应.因此,setState 调用是异步 以及批处理以获得更好的 UI 体验和性能.

This is because setState alters the state and causes re rendering. This can be an expensive operation and making it synchronous might leave the browser unresponsive. Thus the setState calls are asynchronous as well as batched for better UI experience and performance.

来自文档:

setState() 不会立即改变 this.state 而是创建一个待处理的状态转换.调用 this 后访问 this.state方法可能会返回现有值.没有保证调用 setState 和调用的同步操作可能进行批处理以提高性能.

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

使用带有 setState 的回调方法:

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

To check the updated state value just after the setState, use a callback method like this:

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 方法不会立即改变状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆