Lesson 9 of 30
Keeping fetched data fresh over time is a different problem than fetching it once, and the three real patterns for it trade request volume against how quickly staleness gets noticed.
11 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
A component sets up a `setInterval`-based poll but the effect's cleanup function never calls `clearInterval`. What's the resulting bug?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
An initial fetch answers "what's the data right now." Staying fresh over time is a separate concern, and there are three concrete, commonly-used patterns for it:
setInterval, or a data-fetching library's built-in polling option). Simple and predictable, but it burns requests even when nothing has changed, and it needs a real cleanup step or the interval keeps running after the component that started it is gone.These aren't mutually exclusive — a real app commonly combines refetch-on-focus and refetch-on-reconnect as cheap always-on defaults, and reserves fixed-interval polling for the specific data that genuinely needs to update without any user interaction at all (a live order status, a build's progress).
function useOrderStatus(orderId: string) {
const [status, setStatus] = useState<string | null>(null);
const fetchStatus = useRef(async () => {});
// Keep the ref pointing at a function that closes over the *current* orderId.
fetchStatus.current = async () => {
const res = await api.getOrderStatus(orderId);
setStatus(res.status);
};
useEffect(() => {
const id = setInterval(() => {
fetchStatus.current(); // always calls the latest version, never a stale one
}, 5000);
return () => clearInterval(id); // real cleanup — no leaked interval on unmount
}, []); // empty deps: the interval itself is created once, the ref keeps it current
return status;
}
clearInterval in the cleanup function is a real, common memory leak. The interval keeps firing after the component unmounts, calling setState on an unmounted component and doing pointless work indefinitely.setInterval bug, distinct from the leak above — the interval runs fine and never leaks, it just keeps acting on old data because the callback it was given closed over values from when the interval was first created."How would you keep this dashboard's data reasonably fresh without hammering the server?" is a real question, and naming all three patterns — plus the specific setInterval cleanup and stale-closure gotchas — shows you've actually debugged a leaking or stuck polling loop before, not just read the word "polling" in a doc.