Reputation: 1032
State prior to change looks like this:
foreignBases: [
{
base: {
id: "5b8125ec14bb4f35f8f01aa9",
...
},
baseuser: {
userId: "tester1",
...
}
},
{ base: { ... }, baseuser: { ... } }
]
via dispatch the user changes a boolean in the baseuser
key to true
, the reducer is then supposed to update the state for this particular key value pair, but I can't seem to get it right with this:
for (let i = 0; i < state.foreignBases.length; i++) {
if (action.baseUser.created === state.foreignBases[i].baseuser.created) {
return Object.assign({}, state, {
foreignBases: [
...state.foreignBases,
{
base: { ...state.foreignBases[i].base },
baseuser: action.baseUser
}
]
});
}
This just adds another object to the state, when I really just need to replace one boolean of baseuser in one object
Upvotes: 1
Views: 1410
Reputation: 7399
Be sure to check below for updates.
The spread operator is re-inserting the entire foreignBases, and then you're adding another object with what I assume is your intended mutation.
I'm thinking you mean something like this (untested)
for (let i = 0; i < state.foreignBases.length; i++) {
if (action.baseUser.created === state.foreignBases[i].baseuser.created) {
let foreignBases = [...state.foreignBases];
foreignBases[i].baseuser = action.baseUser;
return Object.assign({}, state, {foreignBases});
}
}
Update: @devserkan reminded me that the spread operator "does not do a deep copy", which is a no-no in Redux! So I went looking for the updating an item in an array official pattern, which I believe is applied like this (again, untested):
let foreignBases = state.foreignBases.map((foreignBase) => {
if (action.baseUser.created === foreignBase.baseuser.created) {
return {action.baseUser};
} else {
return foreignBase
}
});
return Object.assign({}, state, {
...foreignBase,
baseuser: action.baseUser
});
Update 2: @devserkan in the comments again contributes valuable insight, this time fixing the original for loop, by nesting in parts of the state object. Which is similar to mutation. This approach avoids that and allows you to still use a for loop.
for (let i = 0; i < state.foreignBases.length; i++) {
if (action.baseUser.created === state.foreignBases[i].baseuser.created) {
const newItem = {
...state.foreignBases[i],
baseuser: action.baseUser
};
const newforeignBases = Object.assign([], state.foreignBases, {
[i]: newItem
});
return Object.assign({}, state, { foreignBases: newforeignBases });
}
}
Upvotes: 2