All questions

Realtime Search with Cache

Premium

Realtime Search with Cache

Build a search box that fetches results as the user types — but does it cheaply. Every keystroke could fire a network request; a good realtime search avoids that three ways. It debounces typing so it only searches once you pause, caches each query's results so repeating a search is instant, and dedupes in-flight requests so two identical searches that overlap share a single fetch instead of hitting the network twice. This is the React variant, built with useState for what renders and useRef for the caches.

Task

The starter App.tsx renders the resting UI — an empty input, a "Type to search" status, and no results. Wire up the logic:

  1. Debounce. In a useEffect keyed on query, wait 300ms after the last keystroke before searching (setTimeout, cleared on the next change).
  2. Cache. Keep a useRef Map of query to results. If the query is already cached, show it instantly and set the status to cached.
  3. Dedupe in-flight requests. Keep a useRef Map of query to the pending Promise. If a fetch for that exact query is already running, await the same promise instead of starting a second one. When it resolves, store the result in the cache and remove the in-flight entry.

A provided searchAPI(query) resolves after ~400ms with the items whose name contains the query (case-insensitive).

Examples

  • Type re, pause. After 300ms it fetches; the status reads fetched · N results and the list fills in.
  • Clear the box and type re again. This time it is in the cache, so results appear instantly and the status reads cached · N results.
  • Type re, and before the 400ms fetch finishes, trigger re again. Only one request goes out — the second search awaits the first's promise.

Notes

  • The Maps are not state. The cache and the in-flight map are read and written synchronously inside async code; they must never trigger a re-render, so they live in useRef, not useState.
  • Cache the key as you search it. Normalize (trim + lowercase) once so Re and re hit the same cache entry.
  • Don't worry about eviction or errors. The cache grows unbounded and searchAPI never rejects — realistic LRU and error states are out of scope here.

Unlock the solution & editor

  • Runnable editor + tests

    Solve in the browser with instant Jest feedback.

  • Detailed solutions

    Walkthroughs, edge cases, and complexity notes.

  • Multi-framework variants

    React, Vue, Vanilla, Angular — same question, different stacks.

Upgrade to Premium