Reputation: 22530
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
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
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