A game score tracker shows a running total and a "Triple Score (+3)" button that is supposed to add 3 points with a single click. Clicking the button only increments the score by 1 each time, so after three clicks the display reads 3 instead of 9.
Click the Triple Score button once - the score goes up by 1 instead of 3. After three clicks the score reads 3, not 9.
Score is not a live value that changes the moment you call setScore - it holds a fixed value for the entire duration of handleTriple.
Score is not a live value that changes the moment you call setScore - it holds a fixed value for the entire duration of handleTriple.
Why this fixes it
Each call to setScore(score + 1) reads score from the render-time snapshot - the same value from before the button was clicked. React queues three requests to set score to (snapshot + 1), and because all three target the same value they collapse into a single update, leaving the score one higher instead of three. Replacing each with setScore((s) => s + 1) passes a functional updater that receives the latest queued value from React's internal update queue rather than the snapshot. React applies the three functional updaters in sequence, chaining from snapshot to snapshot + 1 to snapshot + 2 to snapshot + 3, so each click correctly adds 3.