← Recipes

阅读中文版本

Implement Optimistic UI Updates with Rollback

Apply a UI change immediately, reconcile it with the server response, and restore the previous state when the request fails so the interface never lies.

~35 minfrontenduxstate-management

Task

Add optimistic updates for a mutation and roll them back when the server rejects or the request fails.

When to use this

A toggle feels laggy because it waits for the server round trip, yet showing the change early risks leaving the UI wrong after a failure.

Prerequisites

  • A client state store or component state
  • An API call that can fail or return a conflicting value

Steps

1. Capture the previous state before applying the optimistic change.

Expected output: A rollback snapshot exists for each in-flight mutation.

2. Apply the optimistic update and mark the entity as pending.

Expected output: The UI reflects the intended result instantly.

3. On success, replace the optimistic value with the server value; on failure, restore the snapshot and surface an error.

curl -X POST https://api.example.com/posts/1/like

Expected output: Server truth wins and failures do not leave stale state.

4. Cancel or ignore out-of-order responses using a request token.

Expected output: A slow earlier response cannot overwrite a newer one.

Troubleshooting

Problem

Flicker when responses arrive out of order

Solution

Tag each mutation with a monotonic id and discard responses older than the latest applied one.

Problem

Rollback loses concurrent edits

Solution

Scope rollback to the entity touched by the mutation instead of replacing the whole store.

Limitations

  • Optimistic updates are inappropriate when the server may transform the value in ways the client cannot predict.
  • Irreversible actions should not be shown as complete before confirmation.

Context

Add optimistic updates for a mutation and roll them back when the server rejects or the request fails. A toggle feels laggy because it waits for the server round trip, yet showing the change early risks leaving the UI wrong after a failure.

Steps

  1. Capture the previous state before applying the optimistic change. Expected: A rollback snapshot exists for each in-flight mutation.
  2. Apply the optimistic update and mark the entity as pending. Expected: The UI reflects the intended result instantly.
  3. On success, replace the optimistic value with the server value; on failure, restore the snapshot and surface an error. Expected: Server truth wins and failures do not leave stale state.
  4. Cancel or ignore out-of-order responses using a request token. Expected: A slow earlier response cannot overwrite a newer one.
const prev = store.get();
store.set({ ...prev, liked: true });
try { store.set((await api.like(id)).data); }
catch { store.set(prev); toast.error('Could not save'); }

Verify

  • A rollback snapshot exists for each in-flight mutation.
  • The UI reflects the intended result instantly.
  • Server truth wins and failures do not leave stale state.
  • A slow earlier response cannot overwrite a newer one.

Limits

  • Optimistic updates are inappropriate when the server may transform the value in ways the client cannot predict.
  • Irreversible actions should not be shown as complete before confirmation.