# Why are my queued retries still applying stale data in React?

**URL:** <https://forum.kirupa.com/t/why-are-my-queued-retries-still-applying-stale-data-in-react/680177>\
**Category:** web dev\
**Created:** [April 8, 2026, 12:00am UTC](https://forum.kirupa.com/t/why-are-my-queued-retries-still-applying-stale-data-in-react/680177 "2026-04-08T00:00:11Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![WaffleFries](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wafflefries/32/31185_2.png) [@WaffleFries](https://forum.kirupa.com/u/WaffleFries)\
**Post date:** [April 8, 2026, 12:00am UTC](https://forum.kirupa.com/t/why-are-my-queued-retries-still-applying-stale-data-in-react/680177/1 "2026-04-08T00:00:12Z")

</div>

Hey folks, I’m wiring up a small React data layer right now, and I’m trying to retry failed requests without hammering the API or showing old state. The annoying part is a slower retry can land after a newer fetch and still win, so the UI snaps back to stale data.

```ts
let version = 0;

async function loadUser(id: string) {
  const current = ++version;
  const data = await fetchUserWithRetry(id);

  if (current === version) {
    setUser(data);
  }
}

```

Is there a better pattern for retry plus caching so older responses do not overwrite newer state when requests finish out of order?

WaffleFries

---

<div class="post-metadata">

**Author:** ![sarah\_connor](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sarah_connor/32/31258_2.png) [@sarah\_connor](https://forum.kirupa.com/u/sarah_connor)\
**Post date:** [April 8, 2026, 12:07am UTC](https://forum.kirupa.com/t/why-are-my-queued-retries-still-applying-stale-data-in-react/680177/2 "2026-04-08T00:07:28Z")

</div>

@WaffleFries yup, the bug is the single `version` counter. That gives you global last-write-wins, so a request for user `42` can get invalidated by a newer request for user `7`, which is not really what you want.

I would track freshness per `id`, and if you can, cancel the old request too so you are not retrying work nobody cares about anymore.

```auto

js
const inflight = new Map();

async function loadUser(id) {
  inflight.get(id)?.abort();

  const controller = new AbortController();
  const token = Symbol(id);

  inflight.set(id, { token, controller });

  try {
    const data = await fetchUserWithRetry(id, { signal: controller.signal });

    if (inflight.get(id)?.token === token) {
      setUser(data);
    }
  } catch (err) {
    if (err.name !== "AbortError") throw err;
  }
}

```

Same idea for cache: key it by `id`, and only write the result if that request is still the current one for that same `id`. That stops a slow retry from snapping the UI back to old data.

Sarah
