For example, current state is:
{
data: [
{id: 1, number: 100},
{id: 2, number: 200},
{id: 3, number: 300}
]
}
Action is:
const action = (id, number) => {
return {id: id, number: number}
}
How to implement reducer that it meets the following requirements:
- If the state (array of objects) doesn't have an object with the same id as an ining object - push the ining object to the state;
- If the state has an object with the same id as an ining object - update this object in state with number field value of an ining object.
CASE 1:
//ining object
{id: 4, number: 400}
//result
{
data: [
{id: 1, number: 100},
{id: 2, number: 200},
{id: 3, number: 300},
{id: 4, number: 400}
]
}
CASE 2:
//another ining object
{id: 2, number: 250}
//result
{
data: [
{id: 1, number: 100},
{id: 2, number: 250},
{id: 3, number: 300},
{id: 4, number: 400}
]
}
Maybe it has a simple solution, but I can't find the right approach to solving this problem:) Also I would like to know what is the best practice in cases like this.
Thank you in advance
For example, current state is:
{
data: [
{id: 1, number: 100},
{id: 2, number: 200},
{id: 3, number: 300}
]
}
Action is:
const action = (id, number) => {
return {id: id, number: number}
}
How to implement reducer that it meets the following requirements:
- If the state (array of objects) doesn't have an object with the same id as an ining object - push the ining object to the state;
- If the state has an object with the same id as an ining object - update this object in state with number field value of an ining object.
CASE 1:
//ining object
{id: 4, number: 400}
//result
{
data: [
{id: 1, number: 100},
{id: 2, number: 200},
{id: 3, number: 300},
{id: 4, number: 400}
]
}
CASE 2:
//another ining object
{id: 2, number: 250}
//result
{
data: [
{id: 1, number: 100},
{id: 2, number: 250},
{id: 3, number: 300},
{id: 4, number: 400}
]
}
Maybe it has a simple solution, but I can't find the right approach to solving this problem:) Also I would like to know what is the best practice in cases like this.
Thank you in advance
Share Improve this question asked Oct 13, 2020 at 21:21 HexenHexen 501 silver badge6 bronze badges 2- Add logic to update or insert in your reducer. – Berk Kurkcuoglu Commented Oct 13, 2020 at 21:27
-
Another approach that might be possible is to swap out the array you store in redux for a Record that uses the
id
of each object as a key. This means that checking an id exists is as simple as!!data[id]
and assigning to itdata[id].number = 500;
. Depending on how plex the reducer is an what other actions it requires this could possibly be an option. The redux docs have more information – Jacob Smit Commented Oct 13, 2020 at 21:37
2 Answers
Reset to default 4I changed your action to use the payload
property, but if you want you can remove it. (It's more proper to have it)
const reducer = (state, action) => {
switch(action.type) {
case 'UPDATE_OR_INSERT':
return {
data: [
...state.data.filter(x => x.id !== action.payload.id),
action.payload,
]
}
default:
}
return state;
}
console.log(
reducer({
data: [
{id: 1, number: 100},
{id: 2, number: 200},
{id: 3, number: 300},
{id: 4, number: 400}
]
}, { type: 'UPDATE_OR_INSERT', payload: {id: 2, number: 250}}));
How do you think of this solution?
const testState = {
data: []
}
export default (state = testState, action) => {
switch(action.type){
case "SET_DATA":
return [
...state.data.filter(d => d.id !== action.payload.id),
action.payload,
];
default:
return state;
}
};