All questions

useSWR

Premium

useSWR

"Stale-while-revalidate" is a caching strategy that makes apps feel instant: when you request data, immediately return whatever's in the cache (even if stale), then refetch in the background and update. Navigate back to a page and you see last time's data at once, refreshed a moment later. useSWR (the pattern behind the popular library) does this with a shared, module-level cache, request deduplication, and cross-component updates.

Implement useSwr(key, fetcher). Return { data, error, isValidating, mutate }. Serve the cached data for key immediately, revalidate in the background, dedup concurrent requests for the same key, and let mutate write the cache and notify every mounted component using that key.

Signature

function useSwr(key, fetcher) {
  // returns { data, error, isValidating, mutate }
}

Examples

const { data, error, isValidating } = useSwr(`/api/user/${id}`, fetchJson);
if (error) return <Error />;
if (!data) return <Skeleton />;         // no cache yet
return <Profile user={data} stale={isValidating} />;
// Optimistic update: write the cache now, revalidate after the mutation.
const { data, mutate } = useSwr('/api/todos', fetchTodos);
await saveTodo(todo);
mutate([...data, todo]); // update every component showing '/api/todos'

Notes

  • Cache-first — return cache.get(key) synchronously (stale), then fetch and update. The cache is module-level, shared across all components.
  • Dedup — track in-flight requests by key; concurrent hooks for the same key await one promise, so the fetcher runs once.
  • Shared updates — keep a set of subscribers per key; writing the cache notifies all of them to re-render.
  • mutate(data?, revalidate = true) — optionally write data to the cache (optimistic) and re-fetch; returns a promise. Subscribe on mount, unsubscribe on unmount.

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