Returning the (changed) previous state within a setState
that one gets from the useState
hook doesn't seem to alter state. Run the following straight forward snippet
function App(){
const [state, setState] = React.useState([{x: 0}])
function changeCount(){
setState(prevState => {
console.log('before', prevState[0])
const newState = [...prevState]
newState[0].x += 1 //the shallow copy newState could potentially change state
console.log('after', prevState[0])//here x gets bigger as expected
return prevState //instead of newState we return the changed prevState
})
}
//checking state shows that x remained 0
return <div className='square' onClick={changeCount}>{state[0].x}</div>
}
ReactDOM.render(<App/>, document.getElementById('root'))
.square{
width: 100px;
height: 100px;
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<div id='root'></div>
setState
. Within setState
we make a shallow copy newState
of the previous state. By changing the copy we change the prevState
(maybe unintentionally) as the console confirms. Returning the changed previous state form setState
however doesn't change the state as the count remains 0. If we were to return the newState
, the behavior would be as expected.
Repeating this, shows that prevState
gets bigger, it just doesn't seem to represent the previous state anymore.
Why is that? I made this minimal example on codepen...