React Course
React
/
Advanced

Mutations (React Query)

Definition

In TanStack Query, a Mutation is used to create/update/delete data (POST, PUT, DELETE), whereas a Query is used to read data (GET).

Explain Like I'm New

If a Query is asking the librarian for a book to read, a Mutation is handing the librarian a brand new book to add to the shelf. Because the shelf has changed, you need to tell the librarian to update their catalog (Query Invalidation).

Real World Example

When a user submits a "Create Post" form, you use `useMutation()`. On success, you tell TanStack Query to invalidate the `["posts"]` query key. TanStack Query will automatically trigger a background fetch for the new list of posts, updating the UI seamlessly.

Common Use Cases

  • Submitting forms
  • Liking a post or deleting an item
  • Tracking the loading state of a POST request

Interactive Example

/* 
// Conceptual Example - Requires @tanstack/react-query
import { useMutation, useQueryClient } from "@tanstack/react-query";

const addPost = async (newPost) => {
  const res = await fetch("/posts", {
    method: "POST",
    body: JSON.stringify(newPost)
  });
  return res.json();
};

export default function CreatePostForm() {
  const queryClient = useQueryClient();

  // Setup the mutation
  const mutation = useMutation({
    mutationFn: addPost,
    onSuccess: () => {
      // Tell React Query that the "posts" data on the server has changed.
      // It will automatically refetch the "posts" query in the background!
      queryClient.invalidateQueries({ queryKey: ["posts"] });
      alert("Post created!");
    }
  });

  const handleSubmit = () => {
    // Execute the mutation
    mutation.mutate({ title: "My New Post" });
  };

  return (
    <div>
      <button onClick={handleSubmit} disabled={mutation.isPending}>
        {mutation.isPending ? "Saving..." : "Create Post"}
      </button>
      {mutation.isError && <p>Error: {mutation.error.message}</p>}
    </div>
  );
}
*/
console.log("Mutations handle the write operations, Queries handle the reads.");

Interview Questions

basic

  • What is the difference between `useQuery` and `useMutation`?
  • Does a mutation run automatically when the component mounts?

intermediate

  • How do you trigger a mutation?
  • What does `queryClient.invalidateQueries` do?

advanced

  • What is the difference between `mutate` and `mutateAsync`?
  • How do you implement an Optimistic Update during a mutation?

trick

  • If a mutation fails, does it automatically retry like a query does?

Flash Cards

Question

Does a mutation run automatically?

Click to reveal answer
Answer

No. Queries run automatically when the component mounts. Mutations return a `mutate` function that you must manually call (e.g., inside an `onSubmit` handler).

Question

What does invalidateQueries do?

Click to reveal answer
Answer

It marks a specific query cache (like `["todos"]`) as "stale" and immediately triggers a background refetch. This is the standard way to ensure the UI updates after you add or delete an item.

Question

Does a mutation automatically retry on failure?

Click to reveal answer
Answer

No. By default, `useQuery` will retry failing GET requests 3 times because reading data is safe. Mutations (POST/DELETE) default to 0 retries because repeating a POST request could result in duplicate charges or duplicate data in the database.