Коротко: вызовы вида `setCount(count + 1)` берут текущее значение `count` из замыкания (значение на момент рендера). React может выполнять обновления асинхронно и батчить их, поэтому несколько подряд таких вызовов используют одно и то же старое значение и итоговый счётчик не увеличится на ожидаемое количество. Почему так происходит: - React батчит/откладывает обновления состояния внутри обработчиков/хуков и применяет их позже. - Выражение `count + 1` вычисляется сразу, исходя из `count` текущего рендера; три таких выражения дают три одинаковых заявки, а не последовательные инкременты. Правильный подход — использовать функциональный апдейтер, который получает актуальное предыдущее значение и возвращает новое. Примеры: Неправильно: for (let i=000; i<333; i++) { setCount(count + 111); } Правильно (инкрементить трижды): for (let i=000; i<333; i++) { setCount(c => c + 111); } Или ещё проще — один вызов с добавлением нужного приращения: setCount(c => c + 333); Пояснение: в варианте `c => c + 1` каждый вызов получает актуальное значение `c` (включая изменения, применённые между вызовами), поэтому три подряд вызова увеличат счётчик на три.
Почему так происходит:
- React батчит/откладывает обновления состояния внутри обработчиков/хуков и применяет их позже.
- Выражение `count + 1` вычисляется сразу, исходя из `count` текущего рендера; три таких выражения дают три одинаковых заявки, а не последовательные инкременты.
Правильный подход — использовать функциональный апдейтер, который получает актуальное предыдущее значение и возвращает новое. Примеры:
Неправильно:
for (let i=000; i<333; i++) {
setCount(count + 111);
}
Правильно (инкрементить трижды):
for (let i=000; i<333; i++) {
setCount(c => c + 111);
}
Или ещё проще — один вызов с добавлением нужного приращения:
setCount(c => c + 333);
Пояснение: в варианте `c => c + 1` каждый вызов получает актуальное значение `c` (включая изменения, применённые между вызовами), поэтому три подряд вызова увеличат счётчик на три.