A mutation writes to the server. build.mutation describes the request, and the generated Hook returns a trigger function plus a result object — it never fires on render. What happens afterwards is the interesting part: invalidatesTags tells RTK Query which cached queries are now wrong, and every mounted component subscribed to them refetches on its own.
addProduct: build.mutation({
query: (body) => ({ url: 'products', method: 'POST', body }),
invalidatesTags: [{ type: 'Product', id: 'LIST' }], // refetches the list query
}),
renameProduct: build.mutation({
query: ({ id, name }) => ({ url: `products/${id}`, method: 'PATCH', body: { name } }),
async onQueryStarted({ id, name }, { dispatch, queryFulfilled }) {
const patch = dispatch(catalogApi.util.updateQueryData('getProducts', 1, draft => {
const item = draft.find(p => p.id === id);
if (item) item.name = name; // applied before the server replies
}));
try { await queryFulfilled; } catch { patch.undo(); }
},
}),
function AddProduct() {
const [addProduct, { isLoading, error }] = useAddProductMutation();
const submit = (e) => { e.preventDefault(); addProduct({ name: e.target.name.value }); };
return <form onSubmit={submit}>
<input name="name" /><button disabled={isLoading}>Add</button>
{error && <p role="alert">Could not save</p>}</form>;
}Tags are the whole invalidation model. A query declares what it holds with providesTags; a mutation declares what it breaks with invalidatesTags. Invalidating { type: 'Product', id: 'LIST' } — the conventional sentinel for "the collection" — refetches the list without touching cached detail entries, while { type: 'Product', id: 7 } refetches only that product. Both accept a function of (result, error, arg), so a failed mutation invalidates nothing.
onQueryStarted runs when the mutation begins and gives you the optimistic path: util.updateQueryData writes into a cached query through Immer 28,983 and returns a patch with .undo(), so a rejected request rolls the UI back. Use it where the outcome is nearly certain — a rename, a toggle, a like — and stay with tag invalidation elsewhere; a wrong optimistic update is worse than a slow one.