React's Stale Closure Problem in Hooks

A `useEffect` closure captures props and state from its render. If the effect doesn't re-run, its functions can operate on old, "stale" data. This surfaces in timers or socket listeners. The footgun is omitting dependencies, which causes these subtle bugs.
A `useEffect` closure captures props and state from the render it was created in. If its dependency array is empty (`[]`), its internal functions can operate on old, "stale" data from the initial render, even after state updates. This commonly appears in long-running effects like `setInterval` timers or WebSocket listeners where re-running the effect is undesirable. The `useEffectEvent` hook solves this, but don't use it as a blanket way to ignore the dependency linter; it's for event-like logic, not hiding dependency issues.
Read the original → react.dev
- #react
- #hooks
- #closures
- #state management
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.