jammy
jammy

Reputation: 977

calculation and changing state inside setstate in reactjs

I have two states result which initially set to zero and val initially set to 1. In the multiply function, I change the states as followed.

multiply(){

    console.log('multiply is clicked');

    console.log('numberformed is '+this.state.numberformed);
    this.setState(()=>{
        return{


          val:this.state.val*this.state.numberformed,
          result:this.state.val,


        };

    });

   }

Here this.state.numberformed outputs 12 as I checked using console. I want the result to be equal to 12 so I first changed val as it is seen in the code but the result still reads 1 which is the initial state of val and not the changed state of val.How should I do this?

Upvotes: 0

Views: 1538

Answers (1)

Phil
Phil

Reputation: 141

The tricky part of setState is that the name is slightly misleading. It's actually more like scheduleStateUpdate.

The function you supply to setState returns an object that React will merge with this.state when it updates. Before the update happens, this.state always refers to the current state. Inside the return statement, the update definitely has not happened, because the update hasn't even been scheduled yet. The return statement is what schedules the update.

It looks like this might be what you were trying to do:

this.setState(() => {
  const val = this.state.val * this.state.numberformed
  return {
    result: val
  }
})

The brackets for the return statement might be tripping you up. Yes, it looks an awful lot like the brackets for a function body, or something, where statements go. But it's actually returning a javascript object from the function.

The statement

return {
  result: val
}

Looks conceptually more like this:

return (
  { result: val }
)

This will add a key called result to this.state, accessible as this.state.result. In your code, assuming result was actually assigned the value you expected, two keys would have been added to state: val and result, both of which would have exactly the same value.

Since you're updating state with a simple calculation, you could make an even shorter version without using an intermediate variable like val or even a function at all:

this.setState({result: this.state.val * this.state.numberformed})

Or, more readably:

const { val, numberformed } = this.state
this.setState({result: val * numberformed})

This would set this.state.result to the result of the multiplication and leave every other key of this.state unchanged.

Upvotes: 1

Related Questions