Review

Optimistic drop from kiln-load board

Studio managers at Clayline kept waiting on the kiln-load API before a pulled mug disappeared from tonight's bisque board. Wire useMutation with an optimistic filter so Cancel on a piece removes it from the load list immediately, and roll back if the cancel request fails.

React QueryTier 3react-queryoptimisticrollbackcache

Click a line to flag it, pick one or more labels, then submit. If the change looks correct, approve it.

src/features/kiln/useCancelKilnPiece.ts+16-6
11import { useMutation, useQueryClient } from "@tanstack/react-query";
22import { cancelKilnPiece, type KilnPiece } from "@/api/kiln";
33
44const loadKey = (firingId: string) => ["kiln-load", firingId] as const;
55
66export function useCancelKilnPiece(firingId: string) {
77 const queryClient = useQueryClient();
88
9- return useMutation({
10- mutationFn: (pieceId: string) => cancelKilnPiece(firingId, pieceId),
11- onSuccess: () => {
12- void queryClient.invalidateQueries({ queryKey: loadKey(firingId) });
13- },
14- });
9+ return useMutation({
10+ mutationFn: (pieceId: string) => cancelKilnPiece(firingId, pieceId),
11+ onMutate: async (pieceId) => {
12+ await queryClient.cancelQueries({ queryKey: loadKey(firingId) });
13+ queryClient.setQueryData<KilnPiece[]>(loadKey(firingId), (current) =>
14+ (current ?? []).filter((piece) => piece.id !== pieceId),
15+ );
16+ },
17+ onError: () => {
18+ // Undo the optimistic remove if the studio API rejects the cancel.
19+ queryClient.setQueryData<KilnPiece[]>(loadKey(firingId), []);
20+ },
21+ onSettled: () => {
22+ void queryClient.invalidateQueries({ queryKey: loadKey(firingId) });
23+ },
24+ });
1525}