javascript 29 lines · 6 steps

A React hook that refetches on tab focus

A custom hook re-runs a fetch when the user returns to the tab, but only if the data is stale.

Explained by highlit
1import { useEffect, useRef } from 'react';
2 
3export function useRefetchOnFocus(refetch, { staleTime = 30_000 } = {}) {
4 const lastFetchedAt = useRef(Date.now());
5 const refetchRef = useRef(refetch);
6 refetchRef.current = refetch;
7 
8 useEffect(() => {
9 const maybeRefetch = () => {
10 if (document.visibilityState !== 'visible') return;
11 if (Date.now() - lastFetchedAt.current < staleTime) return;
12 
13 lastFetchedAt.current = Date.now();
14 refetchRef.current();
15 };
16 
17 document.addEventListener('visibilitychange', maybeRefetch);
18 window.addEventListener('focus', maybeRefetch);
19 
20 return () => {
21 document.removeEventListener('visibilitychange', maybeRefetch);
22 window.removeEventListener('focus', maybeRefetch);
23 };
24 }, [staleTime]);
25 
26 return () => {
27 lastFetchedAt.current = Date.now();
28 };
29}
01 / 01
STEP 01

Walkthrough

Space play ←→ step click any line
Three takeaways
  1. 1A ref holding the latest callback lets an effect stay subscribed without re-binding listeners on every render.
  2. 2Tracking a last-fetched timestamp turns focus events into throttled, staleness-aware refetches.
  3. 3Effects that add listeners must return a cleanup that removes them to avoid leaks and duplicate handlers.

Related explainers

Share this explainer

Here's the card — post it anywhere.

A React hook that refetches on tab focus — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code