An optimistic-delete rollback and a user-facing Undo button solve different problems. Rollback restores consistency when the server rejects a delete. Undo reverses an action the server may already have accepted. Design their identities, timing and dependent totals separately before using one cache snapshot for both.
Start with an account-and-day-scoped meal list, stable meal IDs and an authoritative delete response. Inventory derived daily totals and any child records. A deletion that disappears from one list but remains in the daily summary has not completed the visible data transition.
Snapshot the operation, not every future change
TanStack Query documents cancelling relevant queries, taking a snapshot, applying an optimistic update and reconciling after success or failure. The pattern needs adaptation when mutations overlap: restoring an old whole-list snapshot can erase changes accepted after that snapshot was taken.
TanStack Query: optimistic updates and rollback patterns
| Step | Visible IDs | Consequence |
|---|---|---|
| Initial snapshot | A, B | Delete A begins |
| Optimistic removal | B | Request pending |
| Another meal is added | B, C | Newer change must survive |
| Whole snapshot rollback | A, B | Incorrectly loses C |
| Targeted illustrative restoration | A, B, C | Retains the later addition |
The fixture is a pure-array demonstration, not a mounted React Query test. Its targeted restoration shows the intended result for this simple case. Real reconciliation must also consider a concurrent correction or successful deletion of A, server ordering and the accepted version of each record. Blindly inserting a stale copy can be wrong too.
Use the authoritative result to finish reconciliation
The reviewed UltraFit360 delete hook cancels a scoped query, snapshots the list, filters the meal and restores the previous list on error. That source establishes a rollback pattern, not an implemented Undo feature. The overlapping-add fixture identifies a scenario worth testing against the full mutation lifecycle.
A refetch can be the simplest way to reconcile complex overlapping edits after settling. If the server returns enough authoritative data, a targeted update may be appropriate. Keep pending operation IDs so a failure callback from an earlier request cannot reverse a newer accepted action. Show a recoverable error without pretending the deleted meal was durably removed.
Give Undo a separate server contract
A proposed Undo could use a reversible tombstone with a restoration window, or another explicit restore operation. Define who can restore, which children return, how totals are rebuilt and what happens after the window closes. If deletion is permanent, a client-only button cannot honestly promise to recover the original record and its relationships.
Proposed action states:
visible → delete_pending → deleted
delete_pending → visible_on_failure
deleted → restore_pending → restored // separate Undo contractThese states are illustrative and do not describe a current backend API. Keep a failed delete message distinct from “Undo successful.” A user should not need to infer whether the server ever accepted the action from a toast that disappears after a few seconds.
Test list state and totals together
Acceptance should cover a delete failure after an add, two deletions settling in reverse order, a refreshed list arriving mid-mutation and an account switch before the response. Verify that each rollback applies only to its originating account and reporting date. Reconcile daily nutrients and any cached preview from the same accepted state.
For a real Undo design, add expired restoration, repeated restore requests and a record changed by another authorized actor. Keep the isolated fixture’s claims narrow: it demonstrates why a whole snapshot can lose newer state, while the production solution still needs testing with the actual cache, API and persistence rules.
Ordering is another part of restoration. In the simple fixture A returns before B and C, but a real list may sort by meal time, creation time or a server sequence. Restore according to that rule rather than whichever array position the rollback happened to capture. Keep any pending addition visible until its own outcome is known. Test totals and ordering together so a correctly restored ID does not appear under the wrong meal group or reporting date.
Bring the supported devices, installed SDK versions and a reproducible lifecycle or UI failure to scope a mobile engineering assessment.
Explore react native development
Is an optimistic-delete rollback the same as Undo?
No. Rollback reconciles a failed delete. Undo reverses an accepted user action and needs its own server-side identity and restoration policy.
Can an Undo button restore a permanently deleted record from cache?
It cannot reliably restore the original server record and relationships without a supported restoration or recreation contract.
