Great job on structuring your taskReducer logic. You're very close, but there are two small issues in your "EDITED_TASK" section that could lead to bugs:
❌ Mistake 1: Using action.taskId in edited logic
You're doing this:
tasks[oldCategory].filter((task) => task.id !== action.taskId);But action.taskId is not passed in the EDITED_TASK payload — you already have the full action.task, so you should access action.task.id.
❌ Mistake 2: Not handling unknown action types
Your reducer doesn't have a fallback return tasks; if the action type doesn't match. This could cause issues if an unexpected action is dispatched.
✅ Corrected Version
export default function taskReducer(tasks, action) {
if (action.type === "ADDED_TASK") {
const category = action.category;
return {
...tasks,
[category]: [...tasks[category], action.task],
};
} else if (action.type === "REMOVED_TASK") {
const category = action.category;
return {
...tasks,
[category]: tasks[category].filter((task) => task.id !== action.taskId),
};
} else if (action.type === "EDITED_TASK") {
const category = action.category; // new category
const oldCategory = action.editedCategory; // previous category
// ✅ If category changed
if (category !== oldCategory) {
return {
...tasks,
[oldCategory]: tasks[oldCategory].filter(
(task) => task.id !== action.task.id
), // ❗ fixed
[category]: [...tasks[category], action.task],
};
}
// ✅ If category not changed
return {
...tasks,
[category]: tasks[category].map((taskItem) =>
taskItem.id === action.task.id ? action.task : taskItem
),
};
}
// ✅ Fallback for unknown action type
return tasks;
}✅ Summary of Fixes
| Problem | Fix |
|---|---|
Used action.taskId in EDITED_TASK | Replaced with action.task.id |
| No fallback return | Added return tasks; at the end |
Would you like me to show example dispatch actions for each case (add, remove, edit)?