- Home
- /
- Tutorials
- /
- React Tutorial
- /
- Updating State Correctly
State and Reducers
Updating State Correctly
Two rules cover nearly every state bug: never change the existing value, and never read the current value to compute the next one without the updater form.
Updates are batched
Calling the setter does not change the variable immediately. React records the request and re-renders once, so count keeps its value for the rest of the current render - and calling the setter three times with the same stale value only moves it once.
Three calls, one increment
jsx
function Batching() {
const [count, setCount] = React.useState(0)
function addThreeWrong() {
// All three read the same count from this render.
setCount(count + 1)
setCount(count + 1)
setCount(count + 1)
}
function addThreeRight() {
// Each receives the latest pending value.
setCount((current) => current + 1)
setCount((current) => current + 1)
setCount((current) => current + 1)
}
return (
<div>
<p>Count: {count}</p>
<button onClick={addThreeWrong}>Wrong (+1)</button>{" "}
<button onClick={addThreeRight}>Right (+3)</button>{" "}
<button onClick={() => setCount(0)}>Reset</button>
</div>
)
}
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<Batching />)