Problem
Event listeners defined inside effects capture state from the render during which they were created. If the listener is attached once and depends on state that later changes, it may continue operating on outdated values.
- ●Dropdown open state toggled by button.
- ●Document click listener attached once on mount.
- ●Listener captures initial 'open' value.
- ●UI state and listener logic fall out of sync.
Because the effect runs only once, the event listener permanently captures the initial value of 'open'. The dropdown state changes visually, but the listener continues evaluating stale state.
Solution
Keep the event listener stable, but separate state freshness from subscription lifecycle. Store the latest state in a mutable ref and read from it inside the listener.
The listener remains attached only once, preventing unnecessary re-subscriptions. State freshness is handled independently through a ref, ensuring the dropdown logic always evaluates the latest value without closure drift.
Closures capture values at creation time. When subscriptions remain stable but state changes over time, logic may silently operate on outdated data. Separating subscription stability from state freshness prevents subtle UI inconsistencies and aligns event handling with real user behavior.
Keywords
stale closure, react event listener bug, click outside issue, frontend state safety, ui correctness