Recognize the stale-response problem

A visitor types a city name, then quickly changes it. The first search might finish after the second and overwrite the correct results with older data. This problem is about ownership of a result, not simply network speed. Each request needs a relationship to the input and screen state that made its response relevant.

Create a controller for each operation

Construct an AbortController, pass its signal to fetch, and keep the controller associated with that request. When a new search replaces the old one, abort the previous controller before starting the replacement. Do not reuse a signal that has already been aborted. A fresh operation needs a fresh controller and an independently managed lifecycle.

Separate cancellation from a real error

An aborted search usually means the user changed direction, so showing a red network failure would be misleading. Handle an expected abort quietly, while still surfacing a genuine connection or server problem. Keep the loading state associated with the latest operation; an older request finishing its finally block must not make a newer request appear complete.

Protect against outdated completion too

Cancellation is useful, but a response may already have reached a stage where application processing is running. A request sequence number or matching query check can ensure that only the current operation updates the screen. For example, assign each search an increasing identifier and compare it before committing results. This complements cancellation rather than replacing its resource-saving purpose.

Connect cleanup to navigation

A component that starts a request during its lifecycle should stop or invalidate it when the component leaves the screen. The same applies when an input dependency changes. Event-owned requests can keep their controller in a ref or other stable operation record. Document the behavior so future code does not accidentally allow two competing writers to the same result state.

Test with deliberately reversed timing

Use local delayed responses for two different queries and make the older query finish last. Confirm that the final heading, result list and loading indicator all describe the new query. Navigate away during a request and check for unnecessary updates. Then test a genuine failure to ensure that distinguishing cancellation has not hidden every kind of error.

Further reading

Put the idea to work.

Explore free browser tools for images, text and developer workflows.

Try a free tool