olo
olo

Reputation: 5271

react increment decrement counts issue

  increment: function() {
    this.setState({
      counter: this.state.counter + 1
    }); 
     console.log(this.state.counter)
  },

  decrement: function(){
    this.setState({
      counter: this.state.counter - 1
    });
     console.log(this.state.counter)
  },

  calFun: functin(){
     this.state.counter * 5; // incorrect
  }

  render: function() {
    return <div>
      <div id='counter'>{this.state.counter}</div> 
      <button onClick = {this.increment}> +1 </button> 
      <button onClick = {this.decrement}> -1 </button> 
     </div>
  }

{this.state.counter} output number shows correctly, however, console.log always counts one more e.g if I click increment twice, console shows 0 and 1, then I click decrement console shows 2, 1 which caused my program runs incorrectly. What I am expecting is 1, 2, then 1,0

how to have real-time correct increment/decrement counts?

UPDATE:

after searching a while I changed to below, now it is working just fine and fast, componentWillUpdate() makes update a little slow

  this.setState({
      counter: ++this.state.counter
  });

 this.setState({
      counter: --this.state.counter
  });

Upvotes: 1

Views: 448

Answers (3)

davnicwil
davnicwil

Reputation: 31007

this.setState() asynchronously updates the value of this.state. Because you make your console.log(this.state) calls synchronously immediately after calling this.setState() the value of this.state has not changed yet at this point - you are just logging the current value.

To access and log the updated this.state, after the asynchronous update has executed, you can use the lifecycle hook componentDidUpdate()

Upvotes: 2

TonyY
TonyY

Reputation: 703

this.setState() is asynchronous method, and it means current state.

So you have two ways to get next state.

1.react-state-promise

2.Use react-component lifecycle methods.

shouldComponentUpdate(nextProps, nextState) / componentWillUpdate(nextProps, nextState)

Upvotes: 1

lunochkin
lunochkin

Reputation: 784

It's because this.setState works asynchronously. If you want to have correct console.logs, you should use code like this:

this.setState({
  counter: this.state.counter - 1
}, () => {
  console.log(this.state.counter);
});

https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

Upvotes: 0

Related Questions