React: Variables inside of state delayed

I´m working on the calculator. My approach involves storing the values an user enters. My main event handler looks like this, so far:

inputDigit(digit){
const {pendingOperation, displayValue} = this.state;
 
if(pendingOperation){
  this.setState({
    displayValue: String(digit),
    pendingOperation: false
  })
 }
value1= parseFloat(displayValue);
this.setState({
  displayValue: displayValue==="0" ? String(digit) :  displayValue + String(digit),
  value: value1
}, () => {
        console.log(this.state.value) 
      })};

Problem is, when I check the logs value1 is always one number behind than the display (for instance, when display is 10, value1 is just 1). This is because setState is async, right?

Do you have a working example of this? A pen or a repo?

I’m having a hard time understanding. If there is a pending operation, you set displayValue twice?

I’d have to see the rest of the code to understand what you’re trying to do, and put in some logging to see what is happening.

One issue that I can see is that you’re not using the functional setState. This is a new pattern that is being recommended. Basically you have an object as the first parameter of your setState but it is no recommended to have a function that returns an object. Issues can arise if you have multiple setStates called or if your new state refers to the old state - both of which you have here. I don’t know if that is the problem, but it would be something I’d look into.

Thank you for the reply. I´m trying to store the value that is currently being displayed (displayValue) inside of state (which would be value) so that I can use it when I have to calculate an operation. The problem is that value is ALWAYS one step behind the displayValue (for instance, if display is 24, value is just 2). Here´s a working example:

It’s not clear to me what you want value to be.

inputDigit(digit) {
  const { displayValue } = this.state;
  this.setState({
    displayValue:
    displayValue === "0" ? String(digit) : displayValue + String(digit),
    value: displayValue
  });
  console.log(this.state.value);
  console.log(this.state.displayValue);
}

There are a couple of problems here. First of all, like I said, if you are referring to state in your setState, then you should use the functional pattern. Secondly, with value: displayValue, what do you think displayValue is referring to? It is referring to the previous displayValue that was extracted with const { displayValue } = this.state; not what you just calculated with displayValue === "0" ? String(digit) : displayValue + String(digit),. As near as I can understand, you want digit there (I’m guessing your intention). Lastly, those console.log statements - remember that setState is asynchronous so there is no guarantee that state will be set before those run. But setState allows you to give it a callback function as a second parameter, that will run after setState is finished.

So, with all that, I get:

inputDigit(digit) {
  this.setState(state => ({
    displayValue: state.displayValue === "0" ? String(digit) : state.displayValue + String(digit),
    value: digit,
  }), () => { console.log(this.state.value, this.state.displayValue); } );
}

Thanks for the answer! I realised the problem: displayValue doesn´t hold the reference to this.state, it just creates a new variable with the value this.state.displayValue has at the moment of execution. I thought it still held the reference to the original.

Your explanation is correct. With primitive types, it’s creating a new variable.