src/hooks/useOptimisticTasks.ts
needs attention
+58 −0
@@ -0,0 +1,58 @@
1+import { useMutation, useQueryClient } from '@tanstack/react-query';
2+import { updateTask, TaskPatch } from '../api/tasks';
3+import type { Task } from '../types/task';
4+
5+export function useOptimisticTasks(boardId: string) {
6+ const qc = useQueryClient();
7+ const key = ['tasks', boardId];
8+
9+ return useMutation({
10+ mutationFn: (patch: TaskPatch) => updateTask(patch),
11+ onMutate: async (patch) => {
12+ const prev = qc.getQueryData<Task[]>(key);
13+ qc.setQueryData<Task[]>(key, (old = []) =>
14+ old.map(t => t.id === patch.id ? { ...t, ...patch } : t)
15+ );
16+ return { prev };
17+ },
18+ onError: (_e, _p, ctx) => qc.setQueryData(key, ctx?.prev),
19+ });
20+}
line 11
BlockingonMutate doesn’t call qc.cancelQueries(key) first. If a background refetch lands between the optimistic write and the server response, it will clobber the optimistic state and the UI will flicker back to the old value.
line 18
NitRollback restores the list but never surfaces the error. Consider wiring the existing pushToast here so users know the toggle didn’t stick.