My reducer looks like this:
const players = (state = {}, action) => {
switch (action.type) {
case 'UPDATE_PLAYERS_CARDS':
return Object.assign({}, state, {
[action.player]: {
name: state[action.player].name,
score: state[action.player].score,
cards: action.cards
}
})
default:
return state
}
}
export default players
Basically, I just want to update the players cards but if I don't include the name and the score, then those get deleted in the new state.
Ideally I need to just do something like this: state[action.player].cards = action.cards
but one of the rules is to never mutate the state.
The method above will work, but that requires me to always know the data structure so if I add something else to it in the future, I would need to remember to e back to this reducer and add that back in so I don't lose it.
Is there a better way to acplish this?
Edit: Thanks to Vijay for the suggestion for multiple object assigns. I ended up getting it to work with this:
case 'UPDATE_PLAYERS_CARDS':
const playerObject = Object.assign(state[action.player], { cards: action.cards });
return Object.assign({}, state, {
[action.player]: playerObject
});
How is that? Let me know if there are any improvements I can make.
My reducer looks like this:
const players = (state = {}, action) => {
switch (action.type) {
case 'UPDATE_PLAYERS_CARDS':
return Object.assign({}, state, {
[action.player]: {
name: state[action.player].name,
score: state[action.player].score,
cards: action.cards
}
})
default:
return state
}
}
export default players
Basically, I just want to update the players cards but if I don't include the name and the score, then those get deleted in the new state.
Ideally I need to just do something like this: state[action.player].cards = action.cards
but one of the rules is to never mutate the state.
The method above will work, but that requires me to always know the data structure so if I add something else to it in the future, I would need to remember to e back to this reducer and add that back in so I don't lose it.
Is there a better way to acplish this?
Edit: Thanks to Vijay for the suggestion for multiple object assigns. I ended up getting it to work with this:
case 'UPDATE_PLAYERS_CARDS':
const playerObject = Object.assign(state[action.player], { cards: action.cards });
return Object.assign({}, state, {
[action.player]: playerObject
});
How is that? Let me know if there are any improvements I can make.
Share Improve this question edited Aug 18, 2016 at 3:08 Drew asked Aug 18, 2016 at 2:39 DrewDrew 6,87219 gold badges65 silver badges97 bronze badges 2- might consider immutable.js and readup on react's native: facebook.github.io/react/docs/update.html – dandavis Commented Aug 18, 2016 at 2:49
-
Are you using babel? Do you have
stage-2
preset enabled? – QoP Commented Aug 18, 2016 at 3:09
2 Answers
Reset to default 6Multiple Object.assign
methods look ugly.
You can do:
return { ...state.action.player, cards: action.cards }
Note: You'll need stage-2
babel preset to use this.
Once the data structure to update bees fairly plex, you can use ImmutableJS 's setIn
, updateIn
methods to do deep updates easily.
Multiple Object.assign might help:
const newState = Object.assign({}, state);
Object.assign(newState.action.player, { cards: action.cards });