When multiple async operations can be in flight (polling, optimistic mutations, React effects, REST hydration + live WebSocket deltas), older responses may arrive last and overwrite newer state. Standardize a pattern that makes each async result apply only if it is still the current/owned operation.
Apply this rule:
setState, capture a “generation” (requestId) or “owner key” (e.g., selected board slug, active session id) and verify it before committing results.Example pattern (generation-aware commit):
const requestGenRef = useRef(0)
const refresh = useCallback(async () => {
const gen = ++requestGenRef.current
try {
const data = await getKanbanTasks()
// Only the latest in-flight request may update state
if (gen !== requestGenRef.current) return
setTasks(Array.isArray(data.tasks) ? data.tasks : [])
} catch (e) {
if (gen !== requestGenRef.current) return
notifyError(e)
}
}, [])
Also guard by selection/ownership:
selectedBoardSlug (or session id) used to start the request, and before set*, verify it still matches the current value.This prevents race-condition clobbering and makes state transitions deterministic under concurrency.
Enter the URL of a public GitHub repository