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.
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/likeExpected 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
- Capture the previous state before applying the optimistic change. Expected: A rollback snapshot exists for each in-flight mutation.
- Apply the optimistic update and mark the entity as pending. Expected: The UI reflects the intended result instantly.
- 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.
- 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.