The issue you're facing—where the sorting only works on the first click but not on subsequent clicks—is because of this line:
const sorted = tasks[category].sort((a, b) => {
return new Date(a.date) - new Date(b.date);
});
❗ Problem
You're mutating the original tasks[category]
array directly by using .sort()
(which sorts in place). So after the first click, the array is already sorted, and clicking again doesn't create a new change—React doesn't re-render unless state changes.
✅ Solution
Make a copy of the array before sorting to prevent in-place mutation:
function handleSorting() {
const sorted = [...tasks[category]].sort((a, b) => {
return new Date(a.date) - new Date(b.date);
});
setSortedTasks(sorted);
}
Or using structuredClone
if deep copy is needed (not here, though):
const sorted = structuredClone(tasks[category]).sort(...);
This way, sortedTasks
will be a fresh array every time, and the component will re-render correctly.
Would you like a version where clicking toggles between ascending and descending sort?
Thanks for the update. The issue is still not solved because you're not making a deep copy of the task array.
❌ Problem:
This line:
const clonseTasks = { ...tasks };
does not clone the inner array (tasks[category]
), so .sort()
is still mutating the original array in tasks
.
✅ Real Solution:
You must clone the array itself, like this:
function handleSorting() {
const sorted = [...tasks[category]].sort((a, b) => {
return new Date(a.date) - new Date(b.date);
});
setSortedTasks(sorted);
}
You don't need to clone the full tasks
object. You just need to clone the specific array before sorting.
✅ Also Fix the setSortingToggle
Order
React state updates are async. You should handle sorting after the new state value is decided. So:
onClick={() => {
const nextToggle = !sortingToogle;
setSortingToogle(nextToggle);
if (nextToggle) {
handleSorting(); // Sort only when toggle is turned ON
}
}}
🛠 Final Fix (Use This Version):
function handleSorting() {
const sorted = [...tasks[category]].sort((a, b) => {
return new Date(a.date) - new Date(b.date);
});
setSortedTasks(sorted);
}
onClick={() => {
const nextToggle = !sortingToogle;
setSortingToogle(nextToggle);
if (nextToggle) {
handleSorting();
}
}};
Let me know if you'd like to implement a toggle between ascending and descending as well.