PassFront
  1. PassFront
  2. База знаний
  3. Хуки

Как работает хук UseState?

Хуки

useState сохраняет значение между рендерами и планирует перерендер при его изменении. Под капотом React хранит состояние не в компоненте, а у себя — в связанном списке хуков на Fiber-узле.

Механика по шагам

const [count, setCount] = useState(0);
  • Первый рендер: React создаёт ячейку состояния, кладёт туда 0, возвращает значение и сеттер.
  • Повторные рендеры: useState(0) возвращает не аргумент, а текущее сохранённое значение (аргумент игнорируется).
  • Вызов сеттера: React сравнивает новое значение со старым через Object.is; если отличается — помечает компонент на перерендер и ставит обновление в очередь.

Почему хуки нельзя вызывать в условиях

Ячейки состояния сопоставляются с вызовами useState по порядку: первый вызов — первая ячейка, второй — вторая. Условный вызов сдвигает порядок, и состояния «перепутаются» — отсюда правило хуков.

Особенности сеттера

  • Батчинг: несколько вызовов в одном обработчике (в React 18 — вообще везде) дают один перерендер.
  • Замыкание: count в текущем рендере — константа; после setCount(count + 1) переменная не изменится, новое значение придёт со следующим вызовом компонента.
  • Функциональная форма: setCount((prev) => prev + 1) — очередь обновлений применяется последовательно, безопасно при множественных обновлениях.
  • Ленивая инициализация: useState(() => expensive()) — функция-инициализатор выполнится один раз.
setCount(count + 1);
setCount(count + 1); // итог: +1 (оба видят старый count)

setCount((c) => c + 1);
setCount((c) => c + 1); // итог: +2

Коротко для собеседования

React хранит state в списке хуков Fiber-узла и сопоставляет его по порядку вызовов (поэтому хуки — только на верхнем уровне). Сеттер сравнивает значение по Object.is, батчит обновления и планирует перерендер; значение в текущем замыкании не меняется. Для зависимости от предыдущего значения — функциональная форма.

Другие вопросы раздела