Brad Waterhouse
Brad Waterhouse

Reputation: 283

React Native updating single property of nested object in state

I am attempting to update a single property of a nested state object and return it to the state. I have the index of the object that I need to update but I am struggling to change one property and add the new object back to the state.

My state object looks like this and I am trying to reduce the lives of a player on a button press.

I have been playing around with using array filter, trying to copy the object and add it back into the state but this then loses the objects position.

this.state = {
  players: {
    {id: 1, lives: 3, name: something},
    {id: 2, lives: 3, name: something}
  }
} 
public removeLife(id): void {
   const player = this.state.players[id];
   player.lives = player.lives - 1;
   this.setState({players[id]: {...player}
   })
}

Any help would be greatly appreciated.

Upvotes: 4

Views: 357

Answers (2)

Brad Waterhouse
Brad Waterhouse

Reputation: 283

After doing some research I found that the best way to update a single object within a nested state is to shallow copy the state, change the object then re-assign the shallowed state object back to the state. Like this:

    public removeLife(event, id): void {
    const newState = Object.assign([], this.state.players);
    const indexOfPlayer = newState.findIndex(selectedPlayer => selectedPlayer.id === id);
    const player = newState[indexOfPlayer];

    player.lives = player.lives - 1;

    this.setState({players: newState})
}

Upvotes: 2

Idan
Idan

Reputation: 4023

Because your state contains an object of objects I suggest you yo make it an array of objects :

this.state = {
  players: [
    {id: 1, lives: 3, name: something},
    {id: 2, lives: 3, name: something}
  ]
}

you need to handle update like this (update player in index 1 for example):

this.setState({
    players: {...this.state.players, 
       players[1]: {...this.state.players[1], lives: this.state.players[1].lives + 1 }
    }
})

or try it (i follow your function):

public removeLife(id): void {
   const player = this.state.players[id];
   player.lives = player.lives - 1;
   this.setState({players: {
       ...this.state.players,
       players[id]: {...player}
       }
   })
}

Upvotes: 0

Related Questions