Случалось ли с вами такое, что состояние обновляется неожиданным образом? Запомните этот вопрос.
Одна из самых обескураживающих вещей в жизни разработчика — это когда он только начинает свой проект и тут бац!
«Оооо, я думаю, это просто небольшая ошибка, я просто исправлю ее и продолжу свой проект, и все будет хорошо».
Итак, следующее, что он делает, он пытается и пытается исправить ошибку, пока у него не получается, и он сразу же теряет мотивацию работать над проектом, и его день становится потерянным.
В этой серии статей об ошибках UseState, часть I, мы поговорим о наиболее распространенных проблемах с UseState и о том, как их исправить.
Итак, случалось ли с вами, когда состояние обновляется неожиданным образом? снова задается вопрос. Если да, то это потому, что многие разработчики reactjs используют useState, не понимая, как он работает под капотом. Давайте рассмотрим этот пример с небольшим приложением:
Это очень простое приложение, которое мы будем использовать для демонстрации. Оно просто обновляет состояние и данные в h1, когда я нажимаю на кнопку увеличения, а также делает это через 2 секунды, когда я нажимаю на кнопку увеличения асинхронно.
Когда я нажимаю на кнопку увеличения:
Когда я нажимаю на кнопку увеличения асинхронно, мы ждем две секунды и затем видим следующее:
Таким образом, кнопки в основном делают одно и то же в течение разных временных интервалов.
Поэтому я хочу продемонстрировать здесь проблему, которая может возникнуть:
Во-первых, обратите внимание, что функция setTimeout, которую я использовал, просто имитирует асинхронное действие, такое как http запрос, где состояние обновляется после его разрешения.
Проблема возникает, когда я сначала нажимаю один раз на кнопку увеличения асинхронно, а затем сразу же после этого нажимаю на кнопку увеличения более одного раза, например, дважды или трижды.
Как вы думаете, что произойдет? Вот что происходит:
Я нажимаю на кнопку асинхронного увеличения:
Конечно, ничего не происходит, пока не пройдет 2 секунды.
НО:в течение этих 2 секунд я также нажимаю на кнопку увеличения ровно три раза:
И по истечении 2 секунд вот результат:
Но почему? У нас уже было 3 в качестве значения, но значение изменилось обратно на 1, неожиданно, верно?
Вот объяснение: Когда вы нажимаете на увеличение асинхронно и javascript доходит до строки ‘setNumber(number +1)’, он сохраняет текущее значение и по истечении двух секунд добавляет единицу к сохраненному значению, а в примере выше число было O, поэтому он добавил 1 и в результате получилась 1.
Это может привести к неожиданному поведению и может разочаровать многих разработчиков, если они не поймут, в чем проблема.
Как же решить эту проблему?
Решение: Использовать обновление с помощью функции обратного вызова в хуке useState.
Вот как:
const increaseAsynchronously = () => {
setTimeout(() => {
setNumber(prevNumber => setNumber(prevNumber + 1));
},2000)
}
Мы предоставили функцию обратного вызова, и она принимает один параметр, который представляет собой текущее значение состояния, поэтому в этом случае все работает отлично. Давайте повторим то, что мы делали раньше:
Я нажимаю на асинхронную кнопку:
Конечно, ничего не происходит, пока не пройдет 2 секунды.
НО:в течение этих 2 секунд я также нажимаю на кнопку увеличения ровно три раза:
И как только прошло 2 секунды, вот результат:
Итак, это работает, вы можете видеть, что теперь результат соответствует ожидаемому.
Спасибо! Надеюсь, это кому-нибудь поможет.
Давайте обсудим это сообщение в разделе обсуждения и лайк за алгоритм.