A mutation is a state-changing request whose UI must represent pending, success, and failure states before synchronized data is refreshed.
In simpler words
Send the write, prevent duplicate clicks while waiting, show failures, and refresh the data that changed.
Interactive product writes use Nest endpoints and TanStack Query mutations in this monorepo.
After this you can
Model pending, success, and error states
Invalidate affected queries after a write
Distinguish Next-owned actions from Nest-owned product writes
Make the mutation visible
A mutation has a lifecycle, not merely an await expression. Disable or otherwise protect the submit action while pending, retain the draft on failure, and give the user an actionable error message.
After success, invalidate the exact Query resource whose representation is stale. A draft form is local client state; RTK is reserved here for client drafts, not as a duplicate cache of Nest ticket lists.
The mutation owns its pending state and marks the list stale after success.
Mistake: navigating before the write succeeds
// Wrong — leaves the page even if Nest rejects the body
onClick={() => { createTicket.mutate(draft); router.push('/tickets'); }}
// Right — navigate in onSuccess after accepted write
onSuccess: (ticket) => router.push(`/tickets/${ticket.id}`)
A route change is not a successful mutation.
Use Server Actions by ownership
Definition
Server Actions can suit Next-owned form workflows, but they are not a reason to move the product API into Next.
In simpler words
Choose the mutation path that owns validation, authorization, and persistence.
Keep optimistic updates only when the rollback behavior is clear and the UI benefits are measurable.
Do not use a browser-side success message as proof that a write was authorized.
Live playground
Mutating data playground
Trigger a mutation and identify the pending, error, and success UI.
Idle
Keep in mind
Disable submit controls while the mutation is pending.
Invalidate the precise affected Query key after success.
Keep drafts local or in RTK; keep remote ticket records in Query.
Test
Check your understanding
At least 10 questions — mix of concept, syntax, practical, and logic. Score ≥ 80% (enforced by the API) to save progress.