Frontend Blocks typescript Intermediate

React Query Mutation with Optimistic Update

Optimistically update the UI before a mutation resolves, then rollback on error.

typescript
import { useMutation, useQueryClient } from "@tanstack/react-query";

export function useToggleLike(moduleId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () => fetch(`/api/modules/${moduleId}/like`, { method: "POST" }),
    onMutate: async () => {
      await qc.cancelQueries({ queryKey: ["module", moduleId] });
      const prev = qc.getQueryData(["module", moduleId]);
      qc.setQueryData(["module", moduleId], (old: any) => ({ ...old, liked: !old.liked }));
      return { prev };
    },
    onError: (_, __, ctx) => qc.setQueryData(["module", moduleId], ctx?.prev),
    onSettled: () => qc.invalidateQueries({ queryKey: ["module", moduleId] }),
  });
}

Prerequisites

  • @tanstack/react-query >= 5

Pro Tips

  • → Always implement onError rollback for data integrity.

Was this module useful?

Share your experience — it helps the team improve.

Leave Feedback

Commercial Licensing

Acquire a production access token or template license for enterprise deployment.

Module Info

Language
typescript
Level
Intermediate
Read time
5 min
Published
Oct 2025
License
Commercial License

Newsletter

New modules every week, directly to your inbox.