Why calling setState method doesn't mutate the state immediately?

前端 未结 3 790
面向向阳花
面向向阳花 2020-11-21 15:22

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 wo

相关标签:
3条回答
  • 2020-11-21 16:07

    Since setState is a async function. That means after calling setState state variable does not immediately change. So if you want to perform other actions immediately after changing the state you should use callback method of setstate inside your setState update function.

    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 //
             });        
          }
       }
    
    0 讨论(0)
  • 2020-11-21 16:20

    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.

    Why setState is asynchronous ?

    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.

    From Doc:

    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.

    Using callback method with setState:

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

    Check this:

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

    0 讨论(0)
  • 2020-11-21 16:20

    This is by-design due to performance considerations. setState in React is a function guaranteed to re-render Component, which is a costly CPU process. As such, its designers wanted to optimize by gathering multiple rendering actions into one, hence setState is asynchronous.

    0 讨论(0)
提交回复
热议问题