0

I understand that react doesn't update state immediately then can someone tell me how i can log this state synchronously as my state is not a boolean and this answer didn't help me setState doesn't update the state immediately. Also i don't understand why after clicking on prev button it increments the value first and then it decrements

    class A extends Component {
      constructor(props) {
        super(props);
        this.state = {
          value: 1
        }
      }


      handleNext() {
        this.setState(prevState => ({
          value: prevState.value + 1
        }));
        console.log(this.state.value);
      }

      handlePrev() {
        if(this.state.value > 1) {
          this.setState(prevState => ({
            value: prevState.value - 1
          }));
        }
        console.log(this.state.value);
      }

     render() {
       <Button bsStyle="primary" id="prev" onClick={() => this.handlePrev()}>Prev</Button>
       <Button bsStyle="primary" id="next" onClick={() => this.handleNext()}>Next</Button>
}
XDX
  • 137
  • 1
  • 2
  • 11
  • 1
    It appears your question is directly answered in the question you linked to – Andy Ray Mar 18 '18 at 00:29
  • Also, your example "works" as it should, clicking prev does not increment the value first and then decrement. http://jsbin.com/hotafikiko/edit?html,js,output - but also, the exact code you pasted does not work directly as it's missing some curly braces and stuff. – Henrik Andersson Mar 18 '18 at 00:58

3 Answers3

2

The second argument to setState is a callback that executes after the state has updated.

  handleNext() {
    this.setState({ value: this.state.value + 1 }, () => ({
      console.log(this.state.value);
    });
  }

From the setState docs:

The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered. Generally we recommend using componentDidUpdate() for such logic instead.

Andy Ray
  • 30,372
  • 14
  • 101
  • 138
2

setState takes a callback as its second argument.

handleNext() {
   this.setState(prevState => ({
          value: prevState.value + 1
        }),() => console.log('updated', this.state.value));

      }
Xantium
  • 11,201
  • 10
  • 62
  • 89
1

You code is fine, try printing this.state.value in your render function.

Example:

class A extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 1,
    };
  }

  handleNext() {
    this.setState(prevState => ({
      value: prevState.value + 1,
    }));
  }

  handlePrev() {
    if (this.state.value > 1) {
      this.setState(prevState => ({
        value: prevState.value - 1,
      }));
    }
  }

  render() {
    const { value } = this.state;
    return (
      <div>
        <h2>{ value }</h2>
        <button id="prev" onClick={() => this.handlePrev()}>Prev</button>
        <button id="next" onClick={() => this.handleNext()}>Next</button>
      </div>
    );
  }
}

It seems like your handlePrev is incrementing then decrementing because you're constantly printing the previous state. So when you decrement you are printing the result of the previous increment.

|---------------------|-------------------------|
|    Current State    |     Your console.log    |
|---------------------|-------------------------|
|          1          |                         | init
|---------------------|-------------------------|
|          2          |            1            | increment
|---------------------|-------------------------|
|          3          |            2            | increment
|---------------------|-------------------------|
|          2          |            3            | decrement
|---------------------|-------------------------|
Patrick Duncan
  • 340
  • 2
  • 9