Reputation: 3409
I have 3 actions ( add_todo,delete_todo,completed_todo). Add and delete works fine but I should add the deleted items to the completed list in order to render that in a separate component. But whenever I try to use, filter or find to get the deleted items I get a null value.
Reducer code :
const initialState = {
todos: [],
completed: [],
};
const todoSlice = createSlice({
name: "todos",
initialState,
reducers: {
add_todo(state, action) {
state.todos = [...state.todos, action.payload];
},
delete_todo(state, action) {
state.todos = state.todos.filter((todo) => todo.id !== action.payload);
},
completed_todo(state, action) {
console.log(state.todos.find((todo) => todo.id === action.payload));
state.completed = [
...state.completed,
state.todos.filter((todo) => todo.id === action.payload),
];
},
},
});
export const todoActions = todoSlice.actions;
export const selectTodo = (state) => state.todos.todos;
export default todoSlice.reducer;
code where i call or dispatch my actions:
function TodoList() {
const dispatch = useDispatch();
const todos = useSelector(selectTodo);
const handleDelete = (id) => {
dispatch(todoActions.delete_todo(id));
dispatch(todoActions.completed_todo(id));
};
// Some code and a button with handleDelete
}
Upvotes: 0
Views: 76
Reputation: 5497
The problem here is by the time you are dispatching the action to get the completed list your deleted todo's is already gone from the state . Instead of dispatching 2 actions . you can do what are asking for in the delete todo
action .
delete_todo(state, action) {
// find the todo to delete
const deletedTodo = state.todos.find((todo) => todo.id === action.payload);
state.completed = [
...state.completed,
deletedTodo,
];
state.todos = state.todos.filter((todo) => todo.id !== action.payload);
},
since your completed todo is nothing but the todo which you are trying to delete . IMHO its logical to do it in the same action which we use to dispatch for deleting a todo .
Upvotes: 1
Reputation: 6982
The actions will be dispatched one after another. After your first action dispatch(todoActions.delete_todo(id));
, you will remove the todo from your state .filter((todo) => todo.id !== action.payload)
.
After that, the second action get's dispatched dispatch(todoActions.completed_todo(id));
. But state.todos.find((todo) => todo.id === action.payload)
will not find it, since it is already removed.
To fix it, you could swap your dispatch calls. First complete it, then remove it. Problem solved :-)
Upvotes: 1