Keep three facts instead of one ambiguous error
At conflict time, retain the attempted draft, the last acknowledged record, and the newer current record returned or fetched under the server contract:
{
canonical: { id: "a", title: "Open", version: 4 },
draft: "My resolution",
baseVersion: 4,
status: "conflicted",
conflict: { id: "a", title: "Other resolution", version: 5 }
}
React's state-structure guidance
is helpful here: do not maintain a second supposedly canonical selected record.
The draft is local intent; canonical and conflict are separate server
snapshots with explicit meaning.
Let the server reject the stale write
The client should submit the version it edited. The server decides whether that
precondition still holds. RFC 9110
describes conditional request semantics such as If-Match; an API may use a
documented version field instead. The exact mechanism belongs to the API, not
to React.
Do not refetch after an unconditional overwrite and call the result a conflict solution. If the server already accepted a stale write, the newer value may already be lost. The precondition must be enforced at the trusted write boundary.
Offer compare, reload, revise, or cancel
The recovery choices should be deliberate:
- Compare the attempted draft with the current record.
- Reload only when the person elects to discard their draft.
- Revise the draft against the current version, then make a new preconditioned request.
- Cancel without implying that anything was saved.
The P97 state model tests an accepted save, a conflict that keeps the draft, a blocked direct retry, revision using the current version, ordinary failure, explicit reload, and explicit cancel. It does not offer automatic merging because arbitrary fields can have business rules a local component cannot infer.
Review the conflict controls for accessibility
When a conflict appears, keep the draft in place and expose a persistent status message rather than moving focus unexpectedly. The compare, reload, revise, and cancel controls must remain keyboard reachable with labels that explain whether they preserve or discard the draft. W3C's status-message guidance is the review route; this draft has no browser or assistive-technology result. The reviewer must exercise the supported keyboard and assistive-technology path before approval.
Do not overstate the component's powers
This interface pattern does not authenticate anyone, authorize a change, merge records, lock a row, or prove durable persistence. It has no browser or live API exercise. Stop before shipping if a conflict discards the attempted draft, the current server record is unavailable for comparison, recovery controls are not keyboard reachable, or retry occurs without a new server precondition.