Возврат (измененного) предыдущего состояния в пределах setState
, полученного из ловушки useState
, похоже, не изменяет состояние. Запустите следующий прямой фрагмент
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
. В пределах
setState
мы делаем поверхностную копию
newState
предыдущего состояния. Изменяя копию, мы меняем
prevState
(возможно, непреднамеренно), как подтверждает консоль. Возвращение измененного
предыдущего состояния из формы
setState
, однако, не меняет состояние, поскольку счетчик остается 0. Если бы мы должны были вернуть
newState
, поведение было бы таким, как ожидалось.
Повторение этого показывает, что prevState
становится больше, просто оно больше не отражает предыдущее состояние.
Почему это так? Я сделал этот минимальный пример на codepen ...