Navigate
Search topics, hooks, and fundamentals
Closures are how JavaScript functions remember variables from where they were created. Understanding closures is essential for every React hook.
π‘ Every React hook relies on closures. Master this concept and useState, useEffect, and useCallback will all make sense.
These are the patterns that trip up developers most often. Switch between Wrong and Fixed to compare the code side by side.
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
const id = setInterval(() => {
console.log(count); // always 0 β stale closure!
}, 1000);
return () => clearInterval(id);
}, []); // empty deps = captures initial count
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}// Prints 3, 3, 3 instead of 0, 1, 2
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// var is function-scoped β one i shared across all iterationsfunction Chat() {
const [message, setMessage] = useState("hello");
useEffect(() => {
const handler = () => alert(message); // stale if message changes
window.addEventListener("keydown", handler);
return () => window.removeEventListener("keydown", handler);
}, []); // missing message in deps!
return <input value={message} onChange={e => setMessage(e.target.value)} />;
}