React Native / Editorial solution guide

Stop obsolete Effects and session publication

Separate subscription cleanup, request freshness, and account ownership when delayed results reach the wrong interface.

About 3 min readContent reviewed

Read-only knowledge base · No public comments

Recognize the symptoms

An earlier search replaces a later result, an old failure covers a new success, or a previous account’s response appears after login changes.

An unmount-only guard prevents publication after the component is removed, but it cannot reject obsolete request or session results while the same component remains mounted with different input or account ownership.

Understand the likely causes

  • Completion order differs from request order, and lifetime alone does not identify the query or account entitled to publish.
  • Success, failure, and busy-state cleanup may use inconsistent gates. Detachment can also leave an already queued callback able to run.

Record start, completion, and commit separately

Use synthetic request tickets and session generations to reconstruct the ordering. Record which owner started each operation, when it completed, and whether publication was accepted. Avoid logging tokens, private query strings, or full payloads. Starting A before B does not require A to complete first; the defect is allowing A to commit after its ownership becomes obsolete. Inspect Effect dependencies and model scope as well as cleanup. A stable component can intentionally survive navigation or account change, so an unmount-only guard can miss the actual failure.

Gate every publication path with the same identity

The program captures both session and request identity. A session change rejects an old completion even when the request counter happens to match. Use the gate immediately before result, failure, and pending-state mutations. In a React Effect, cleanup can revoke that Effect instance’s publication right; in a retained model, session and request invalidation need an explicit owner. This local equality check does not cancel transport or enforce server permission. It establishes only who may publish into the current application state, while actual resource detachment remains a separate responsibility.

javascript Standalone JavaScript model with synthetic local inputs.
function mayPublish(started, current) {
  return started.session === current.session && started.request === current.request;
}
const started = {session: 1, request: 7};
const nextAccount = {session: 2, request: 7};
console.log(mayPublish(started, nextAccount));
console.log(mayPublish(started, {session: 1, request: 7}));
Expected output
false
true

The same request number in another session is a different owner. No request or React Effect is executed.

Keep cancellation and command semantics distinct

Debouncing reduces starts and cancellation may reduce wasted work when the underlying API cooperates. Neither alone proves a callback cannot already be queued or a server command was not accepted. A timeout likewise limits local waiting rather than guaranteeing rollback. For live search, latest-input publication is usually suitable; for a write, uncertain completion may require reconciliation through stable operation identity. Do not automatically discard or retry a transactional operation using the search policy. Keep private caches scoped to the original session so another observer cannot republish obsolete content after the view gate rejects it.

Control dangerous completion orders with a fake

Provide separate deferred responses. Start A, start B, finish B, then finish A; repeat with A rejecting and with session change before A finishes. Verify old work cannot clear the new operation’s busy indicator or write private data into the new cache scope. Also replace a subscription while a callback is queued when the source contract permits that case. Explicit checkpoints are stronger than arbitrary sleeps. Node models verify policy, while actual Effect replacement, native event removal, transport abort, and target UI require their own compatible-host evidence.

Verify the fix

Newer results survive stale success and failure, account changes invalidate old publication rights, and owned listeners are removed without presenting cleanup as remote cancellation.

The course’s local models and promise tests do not certify a renderer, native event source, backend transaction, or device lifecycle. No real account or endpoint is used.

Keep it from recurring

  • Keep lifetime, freshness, session scope, and authoritative permission as separate documented contracts. Preserve the deferred-response and account-switch regression fixtures.

Official references