Volume 3

Q169: useOptimistic, Action State and Pending Mutations

Difficulty: SeniorFrequency: MediumAnswer time: 8-12 minutes

What Interviewers Want To Evaluate

This question checks whether you can design mutation UX in modern React. Interviewers want optimistic updates, pending state, rollback, server authority, duplicate submissions, action state, form status, failure recovery, accessibility, and cache invalidation.

Senior answers should connect optimistic UI to trust, not just speed.

Short Interview Answer

Optimistic UI shows the expected result before the server confirms the mutation. React's useOptimistic helps represent temporary optimistic state, while action-related hooks and form pending state help show submission progress and server results. Optimism is useful when success is likely and rollback is understandable. The server remains authoritative, and the UI must handle failure, duplicate actions, validation errors, and reconciliation.

Detailed Interview Answer

Optimistic UI makes an app feel fast.

Example:

user clicks like
UI increments immediately
request goes to server
server confirms or rejects
UI reconciles with authoritative data

This is not just a rendering trick. It is a product promise.

useOptimistic Mental Model

useOptimistic lets you derive temporary UI state while an async action is pending.

const [optimisticItems, addOptimisticItem] = useOptimistic(
  items,
  (currentItems, newItem) => [...currentItems, newItem],
);

The base state still comes from real data.

The optimistic state layers pending changes on top.

Simple Example

function CommentForm({ comments, createComment }) {
  const [optimisticComments, addOptimisticComment] = useOptimistic(
    comments,
    (current, text) => [...current, { id: "pending", text }],
  );

  async function submit(formData) {
    const text = String(formData.get("text") ?? "");
    addOptimisticComment(text);
    await createComment(formData);
  }

  return (
    <>
      <CommentList comments={optimisticComments} />
      <form action={submit}>
        <textarea name="text" />
        <button type="submit">Post</button>
      </form>
    </>
  );
}

The real implementation should handle errors and unique pending IDs.

Pending State

Pending state answers: "Is the mutation still in flight?"

Use pending state to:

disable duplicate submit when needed
show saving labels
announce progress to assistive tech
prevent conflicting actions
keep safe actions available
avoid losing user input

Do not disable the whole page unless the mutation truly blocks it.

Action State

Modern React and Next.js form patterns can return state from server actions.

The action can return:

field errors
form-level errors
success message
updated metadata
redirect instruction through framework APIs

The client UI reads that state and renders recovery.

Rollback and Reconciliation

Optimism needs a failure plan.

remove pending optimistic item
mark item as failed with retry
replace temporary id with server id
merge server-corrected fields
restore previous value
show validation message

The right choice depends on the action.

A failed chat message may stay visible with retry. A failed payment should not appear successful.

When Optimism Is Appropriate

Good candidates:

like button
favorite toggle
adding a draft comment
marking notification as read
reordering local list
simple preference changes

Risky candidates:

payments
permission changes
account deletion
inventory-limited purchases
legal consent
security-sensitive actions

High-risk actions need explicit confirmation and server authority.

Duplicate Submissions

Optimistic UI can make duplicate submissions easier if pending state is not handled.

Defenses:

idempotency keys
disabled submit button during pending
server duplicate detection
client-side pending item ids
request cancellation where appropriate
clear retry behavior

The server must still protect correctness.

Accessibility

Mutation state should be announced.

aria-live for saved or failed messages
aria-busy for regions being updated
focus management for validation errors
clear button labels during pending state
preserve keyboard position where possible

Fast UI should still be understandable UI.

Common Mistakes

A common mistake is pretending a mutation succeeded before the server can authorize it.

Another mistake is losing user input after failure.

Another mistake is creating duplicate optimistic items.

Another mistake is not reconciling temporary IDs.

Another mistake is hiding validation errors behind generic failure messages.

Senior Trade-Offs

Optimism improves perceived performance but increases state complexity.

Use it when the user understands the temporary state and the failure mode is recoverable.

For risky flows, prefer clear pending state over fake success.

Debugging Workflow

When optimistic UI misbehaves:

track pending ids
simulate slow network
simulate server validation failure
test duplicate submit
verify rollback
verify cache invalidation
check screen reader announcements
confirm final server data wins

Code or Design Example

optimistic update lifecycle
1. capture intent
2. add pending optimistic state
3. send mutation with idempotency key
4. show pending affordance
5. reconcile success or failure
6. invalidate or refresh authoritative data

This lifecycle is more important than any single hook.

Interview Framing

Define optimistic UI, explain useOptimistic, pending state, rollback, server authority, duplicate submissions, and accessibility.

Revision Notes

Optimistic UI is a trust design. It must be fast, honest, recoverable, and reconciled with the server.

Key Takeaways

Show confidence only where failure is recoverable. The server remains the source of truth.

Follow-Up Questions

  1. What is optimistic UI?
  2. What does useOptimistic help with?
  3. When should optimism be avoided?
  4. How do you handle rollback?
  5. How do temporary IDs get reconciled?
  6. How do you prevent duplicate submits?
  7. What should pending state disable?
  8. How do server validation errors return to UI?
  9. How should mutation status be announced accessibly?
  10. How does cache invalidation fit in?

How I Would Answer This In A Real Interview

I would say optimistic UI temporarily reflects likely success while a mutation is pending. I would use it for recoverable actions, keep pending IDs and rollback paths explicit, avoid fake success for risky flows, and always reconcile with authoritative server data.