День 5 изучения React: Батчинг и функциональные обновления
Я думал, что многократный вызов сеттера состояния вызывает несколько рендеров.
Я ошибался.
React умнее. Он использует процесс под названием Automatic Batching (автоматический батчинг).
Вместо того чтобы рендерить после каждого отдельного обновления, React группирует их. Он собирает все обновления и выполняет один единственный рендер. Это повышает производительность.
Вот что я узнал сегодня.
Процесс батчинга Когда вы вызываете несколько функций состояния, React следует такому алгоритму:
- Происходит несколько обновлений состояния.
- React объединяет их в батчи.
- React выполняет один рендер.
- React применяет изменения к UI.
Проблема стандартных обновлений
Я попробовал этот код:
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
Я ожидал, что счетчик изменится с 0 на 3. Но он изменился с 0 на 1.
Это происходит потому, что setCount(count + 1) не означает «увеличить счетчик».
Это означает «установить счетчик в это конкретное значение».
Если count равен 0, каждая строка говорит React установить count равным 1. React объединяет эти вызовы и видит, что последняя инструкция — установить count равным 1.
Решение: Функциональные обновления Чтобы исправить это, нужно использовать функциональное обновление. Оно использует последнее доступное состояние из очереди обновлений.
Правильный способ:
setCount((prev) => prev + 1);
При использовании этого паттерна React передает каждому обновлению самое актуальное значение.
- Первое обновление: 0 + 1 = 1
- Второе обновление: 1 + 1 = 2
- Третье обновление: 2 + 1 = 3
Теперь счетчик действительно достигает 3.
Распространенная ошибка
Однажды я написал:
setCount((prev) => { prev + 1 });
Счетчик стал undefined.
Если вы используете фигурные скобки в стрелочной функции, вы должны использовать ключевое слово return.
Вместо этого используйте:
setCount((prev) => prev + 1);
Основные выводы:
- React объединяет несколько обновлений состояния в батчи для повышения скорости.
- Вызовы
setStateне всегда вызывают немедленный рендер. - Стандартные обновления используют значение из текущего цикла рендеринга.
- Функциональные обновления используют последнее состояние из очереди обновлений.
- React использует внутреннюю очередь обновлений (Update Queue) для управления этими изменениями.
