GitHub

Copyright © 2026 Sumit Paul

Design by Sumit Paul•LinkedIn

LinkedIn

State update after route transition

Avatar

Sumeet Kumar Paul

Frontend Engineer

2 min readSource code
Feb 20, 2026

Problem

A component starts asynchronous work and then a route transition occurs before the work completes. When the async task resolves, it updates state that no longer matches the active route.

Under rapid navigation or slow network conditions, outdated async results can commit state after the user has moved to a different page, causing visual flickers or data appearing briefly in the wrong context.

  • ●Async request triggered on mount.
  • ●User navigates away quickly.
  • ●Async resolves after route change.
  • ●State update applies to outdated screen context.
page.tsx
srcapppracticeroute-transition-state-leakpage.tsx
1useEffect(() => {
2  console.log("[BROKEN] request started for route:", route);
3
4  void (async () => {
5    const data = await fetchData(route);
6    console.log("[BROKEN] request resolved for route:", route);
7    setData(data);
8  })();
9}, [route]);

Because the async callback closes over the original route value, late responses may commit data that no longer matches the current navigation state.

Solution

Associate each route-triggered request with a request identity. Only allow the most recent route request to commit state.

Instead of assuming navigation invalidates previous async tasks, explicitly validate that the response still corresponds to the active route before updating state.

page.tsx
srcapppracticeroute-transition-state-leakpage.tsx
1const requestIdRef = useRef(0);
2
3useEffect(() => {
4  const requestId = ++requestIdRef.current;
5  console.log("[FIXED] request started for route:", route);
6
7  void (async () => {
8    const data = await fetchData(route);
9
10    if (requestId !== requestIdRef.current) {
11      console.log("[FIXED] stale route response ignored");
12      return;
13    }
14
15    console.log("[FIXED] request committed for route:", route);
16    setData(data);
17  })();
18}, [route]);

By validating request identity against the current route, outdated responses are ignored and UI state remains aligned with active navigation context.

Route transitions do not automatically cancel asynchronous work. Treat async results as untrusted until verified against the current navigation intent.

Keywords

route transition bug, react navigation race, state leak, frontend lifecycle issue, ui correctness

More Cases

2 min readFeb 18, 2026

Optimistic UI rollback failure

An optimistic UI update immediately reflects a user action before the server confirms success. If the request fails or multiple toggles occur quickly, the UI can drift away from actual server state.

Avatar

Sumeet Kumar Paul

2 min readFeb 16, 2026

Double submit caused by UI state lag

A submit button is disabled only after state updates to 'loading'. Under rapid user interaction, multiple clicks can occur before the UI visually reflects the disabled state.

Avatar

Sumeet Kumar Paul

2 min readFeb 13, 2026

Stale closure in click outside listener

Event listeners defined inside effects capture state from the render during which they were created. If the listener is attached once and depends on state that later changes, it may continue operating on outdated values.

Avatar

Sumeet Kumar Paul

2 min readFeb 10, 2026

State update after unmount during navigation

When a component starts asynchronous work and the user navigates away before it resolves, the async callback may still attempt to update state. At that point, the component no longer exists in the UI tree.

Avatar

Sumeet Kumar Paul