Store selection as identity
The minimal state is a list snapshot, its documented order or version, and a selected ID:
const [state, setState] = useState({
items: initialItems,
listVersion: 12,
selectedId: "case-a",
notice: "",
});
const selected = state.items.find(item => item.id === state.selectedId) ?? null;
This follows React's state-structure guidance: selected is derived from the canonical list, so
an accepted refresh automatically updates the visible detail. React's
array-state guidance also
applies when replacing the new list immutably.
Handle changed and removed records differently
When a newer list arrives, check whether the selected ID remains present.
| Refresh result | Selected ID | Detail behavior |
|---|---|---|
| Record remains with new fields | Keep it | Show the updated canonical record |
| Record leaves the list or is deleted | Clear it | Explain that it is no longer in this list |
| Snapshot is older than visible state | Keep existing state | Ignore the late result |
| No selected ID | Keep none | Do not invent a default action |
Clearing a removed selection is not an authorization decision and does not tell the person whether the record was deleted, moved, hidden by a filter, or no longer available to them. The product should choose accurate copy based on its server contract.
Require an ordering contract
A list refresh needs an order rule before it can reject an older snapshot. It could use a monotonically increasing list version, request generation, cache generation, or an API-defined entity version. Do not guess from a timestamp whose meaning is not documented.
The local P98 model tests canonical detail updates, explicit removal, stale-list rejection, and invalid selection. It is an in-memory Node model, not a subscription, browser, or keyboard test.
Review removal and focus behavior
When a refresh clears selection, announce the state change in a persistent status message and leave focus in a predictable, valid place. If the removed detail had focus, the product should deliberately move it to a labelled list or replacement heading; if focus is already elsewhere, do not steal it. W3C's status-message guidance is a review route, not a completed assistive-technology test. Review the supported keyboard and assistive-technology behavior before approval.
Keep backend duties separate
Selection does not grant permission, reserve a record, preserve a stale edit, or prove that a server notification was complete. Those are backend and product-contract questions. Stop before shipping if a removed record can remain selected, an older list can replace newer visible data, or the cleared-selection message and focus destination are not reviewable.