A listener types “space,” then changes it to “space history.” The first request is slow. The second returns quickly. If the first response arrives last, a careless interface shows the wrong results under the newer query.

This is an order problem. Reducing the number of requests helps performance, but it does not decide which response is still relevant.

Give each search an identity

Keep a counter or request ID in your search state. Increase it when the active query changes. A response may update the screen only when its ID matches the latest request. Store the submitted query beside the result so the relationship remains clear.

In a browser, an AbortController can cancel work associated with an earlier fetch. Abort the old controller before starting the next search. Treat cancellation as normal behavior rather than an error that needs a red warning.

Still check request identity. Cancellation and completion can happen close together. Your code should remain correct when a response has already arrived or a transport cannot stop all upstream work.

Keep the screen calm

Retain the typed text while loading. If you keep older results visible, label them as updating or dim them without disabling reading. Never silently change the input back to the text from an older response.

Test with deliberate delays: make the first response take two seconds and the second take a tenth of a second. Repeat while clearing the input and leaving the page. The final visible results must belong to the final query, and an unmounted screen must receive no state update.

This check is useful before adding clever caching. A fast wrong result is still wrong.