Lukas Petersson
Lukas Petersson

Reputation: 315

setState on only one variable

I have a react native app with the state:

this.state={
        nameOne:"team 1",
        nameTwo:"team 2",
        pointsForEvents:{
            lap: 1,
            homeRun: 5,
            lyre: 3,
            oneHandCatch: 5,
            burned: 1,
            burnOut: 10,
        }
    }

Then I want to update the variables in pointsForEvents:

<TextInput
        keyboardType="number-pad"
        onChangeText={(lyre) =>{lyre = parseInt(lyre); this.setState({pointsForEvents:{lyre}})}}
        value={this.state.pointsForEvents.lyre+""}
    />

But the setState updates the other variables within "pointsForEvents" as well and since a value is not specified, they are set to undefined. How do I update only this one value.

PS: what is the correct vocabulary for a variable within an object (like components are parents to their child components).

Upvotes: 1

Views: 2650

Answers (2)

Peter Lehnhardt
Peter Lehnhardt

Reputation: 4985

In your code you are actually setting pointsForEvents to a new value, which is an object containing only a single key lyre, therefore the other previously specified keys are not available anylonger and resolve to undefined. If you want to keep the other keys in the object and only update the key lyre, then you have to copy the old object, update only the one key and use this object to set state of pointsForEvents.

Copying of objects can be achieved with the spread operator as shown in the answers. So the following code creates a new object containing all the keys of pointsForEvents plus the updated key lyre with its given value and this is the object you want to set in state. In this case lyre is inserted into the object, but since it was already there, it will only get updated.

{...this.state.pointsForEvents, lyre}

Upvotes: 4

Dan
Dan

Reputation: 8784

You can use the spread operator, like so:

onChangeText = {
  (lyre) => {
    lyre = parseInt(lyre);
    this.setState({
      pointsForEvents: {
        ...this.state.pointsForEvents,
        lyre,
      }
    })
  }
}

In fact, this option would be better:

onChangeText = {
  (lyre) => {
    lyre = parseInt(lyre);
    this.setState((state) => ({
      pointsForEvents: {
        ...state.pointsForEvents,
        lyre,
      }
    }))
  }
}

The reason why the second option is better is because this.setState doesn't update the state right away, so you may see some anomalies.

Upvotes: 1

Related Questions