В реакции мы обычно обновляем переменную состояния по-разному в классе и функциональном компоненте. Поскольку синтаксис обновления в этих двух типах компонентов отличается.
В компоненте класса:
// variable declaration this.state = { count: 0 }
// update value this.setState({ count: this.state.count + 1 })
В функциональной составляющей
// variable declaration const [count, setCount] = useState(0);
// update value setCount(count + 1);
Но в этой статье мы собираемся обсудить только компонент класса, а тема обсуждения — «Как обновить состояние на основе предыдущего состояния». Если мы будем следовать обычной процедуре, мы можем получить некоторые проблемы в некоторых сценариях. Давайте создадим этот сценарий и попробуем решить.
Итак, первый шаг — создать кнопку, а в ее событии onClick вызвать метод приращения для увеличения значения состояния счетчика.
// create a button and a onClick event <button onClick={() => this.increment()}>Increment</button>
// increment method increment = () => { this.setState({ count: this.state.count + 1 }, () => { console.log('Update value:', this.state.count) }) }
До этого момента приложение будет работать правильно. Потому что приведенный выше сценарий очень прост. Давайте попробуем увеличить переменную count пять раз для одного события нажатия кнопки.
// create a button and a onClick event <button onClick={() => this.incrementCountFiveTimes()}>Increment</button> // incrementCountFiveTimes method incrementCountFiveTimes() { this.increment() this.increment() this.increment() this.increment() this.increment() }
Если мы запустим приложение, мы увидим, что increment() вызывается пять раз, а консоль записывает обновленное значение счетчика пять раз. Но если мы посмотрим внимательно, каждый раз обновленное значение счетчика будет одним и тем же, т.е. 1. И это потому, что для повышения производительности реакция может группировать несколько вызовов состояния установки в одно обновление, а обновленное значение не переносится между разными вызовами.
Решение:
Таким образом, в таком сценарии решение этой проблемы заключается в том, что всякий раз, когда нам нужно обновить состояние на основе предыдущего состояния, мы передаем функцию в качестве аргумента this.setState() вместо передачи в объект. Таким образом, обновление increment() будет выглядеть так:
increment = () => { this.setState((prevState) => ({ count: prevState.count + 1 })) }
Это даст нам фактический результат каждый раз в журнале консоли. Потому что здесь мы увеличиваем переменную count с предыдущим состоянием, а не с текущим состоянием.
Первоначально опубликовано на https://codinghub.net.