Reputation: 5331
I have a StackBlitz that you can fork, I found a similar answer but I'm having trouble applying it to my example, I think it's because I have an array of objects.
I have the code working but it's very verbose, and I would like something easier to read that others who use Redux will recognize.
const initialState = [];
const todoReducer = (state, action) => {
switch (action.type) {
case 'ADD_TODO': {
return [...state, {
id: state.length,
name: action.name,
complete: false
}];
}
case 'TOGGLE_COMPLETE': {
let left = state.filter((_, index) => index < action.index)
let right = state.filter((_, index) => index > action.index)
let completed = state.filter((_, index) => index == action.index)
let updatedItem = {
id: completed[0].id,
name: completed[0].name,
complete: !completed[0].complete
}
return [...left, updatedItem, ...right];
}
case 'CLEAR': {
return initialState;
}
default: {
return state;
};
}
}
I feel like the answer is is similar to this one? Update array object in React Redux reducer
In the answer I cited above, his object has state.posts
How can I update my example to be more like this one?
How can I target my Todos if I don't have a similar state object as I can't do something like:
state.todos.complete = false.
I want to write a better reducer for the 'COMPLETE' action. Do I need to modify how my state is structured, ie dopes it need to be an empty object instead of an array of objects?
Upvotes: 3
Views: 3259
Reputation: 4336
Just map
:
case 'TOGGLE_COMPLETE': {
return state.map((item, i) => i === action.index
? {...item, complete: !item.complete}
: item
)
}
You can conditionally update "complete" without iterating multiple times.
Upvotes: 7