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+}
Blocking
onMutatedoesn't callqc.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.NitRollback restores the list but never surfaces the error. Consider wiring the existing
pushToasthere so users know the toggle didn't stick.