Why can a timer or stream callback use stale state?
Answer out loud or in your head first, then compare.
Answer
A function created in a given render has access to the values from that render. If I start a timer once and leave its callback unchanged, it can keep seeing the old value. That's a closure at work, not React “failing to update the variable”.
When I append another chunk of text, setText(previous => previous + fragment) often helps. It gives me the current state needed for the update. It doesn't stop two different conversations getting mixed, though. For that I also need a request ID. If a changing value should rebuild the subscription, I include it in the effect's dependencies and clean up the previous one properly.
Why it matters: Streaming UI easily exposes this bug.
Possible follow-ups: When do you use an updater function, and when do you recreate the subscription?
How did it go? Be honest — “Not yet” puts the question on your review list.
Start with
- B-P07 · What is a closure? — JavaScript, TypeScript and Node.js
- C-P04 · What is useEffect for, and what does the dependency array mean? — React, Next.js and frontend
Further reading
- React: Synchronizing with Effects(opens in a new tab)Docs; accessed 22.10.2026. What Effects are for, cleanup, and protecting against stale results.