Lesson
The Stale Closure Problem
Task
Fix the TV remote
Solution
Fix 1: Use the state setter callback so the handler function always reads the latest value, not the stale one captured at mount.
React.useEffect(() => {
function handleKeyDown(event) {
if (event.code === "Space") {
setIsPlaying((currentIsPlaying) => !currentIsPlaying);
}
}
window.addEventListener("keydown", handleKeyDown);
return () => {
window.removeEventListener("keydown", handleKeyDown);
};
}, []);Fix 2: stop the Spacebar from reaching the window listener when the button is focused, so it toggles once instead of twice.
<button
className="power-button"
onKeyDown={(event) => {
if (event.code === "Space") {
event.stopPropagation();
}
}}
onClick={() => {
setIsPlaying((currentIsPlaying) => !currentIsPlaying);
}}
>
{isPlaying ? <Pause /> : <Play />}
<VisuallyHidden>Toggle playing</VisuallyHidden>
</button>Play with the box below to make the concept click.