bier hier
bier hier

Reputation: 22530

How to update 1 item in state with redux?

I have a reducer and trying to update 1 item in the statearray. It looks like this:

const players = (state = [{name:'John',nrGames:0,nrWins:0},{name:'Ed',nrGames:0,nrWins:0},{name:'Mark',nrGames:0,nrWins:0}], action) => {
    switch (action.type) {

        case 'ADD_PLAYER':
            return [...state,{name:action.name}]

        case 'ADD_WIN':
            return [...state, action.name == 'bla' ? {nrWins:10} : {} ]

        default:
            return state;
    }
};

export default players;

I am trying to figure out how to change the nrWins property for a certain name. So when ADD_WIN is dispatched with name='John' how to just update the John object and up the nrWins property with 1 and not the other objects in the state?

Upvotes: 3

Views: 56

Answers (2)

arpl
arpl

Reputation: 3633

You need to .map over the players and when you find the one the action is describing create a new player with the updated number of wins. For readability I created a function called incWinForPlayer.

const incWinForPlayer = (name) => (player) => {
  return player.name === name
    ? {...player, nrWins: player.nrWins + 1}
    : player
};

const players = (state, action) => {
  switch (action.type) {
    case 'ADD_PLAYER':
      return [...state, {name: action.name}]
    case 'ADD_WIN':
      return state.map(incWinForPlayer(action.name));
    default:
      return state;
  }
};

export default players;

Upvotes: 3

weisk
weisk

Reputation: 2540

The "recommended" approach is to slice the old array up to the new item, concat it with the modified one, and concat it with the rest of the array.

Make sure that your action returns the whole new item, and the index you want to modify.

Something like:

case 'ADD_WIN':
  return [
    ...array.slice(0, action.index),
    action.item,
    ...array.slice(action.index)
  ];

Edit 1: source https://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html#inserting-and-removing-items-in-arrays

Upvotes: 0

Related Questions