useState

Тема дорожной карты · React

Хук useState — встроенный хук React, добавляющий локальное состояние в функциональный компонент; он возвращает значение состояния и функцию-setter в виде двухэлементного массива. При вызове useState(initialValue) React сохраняет состояние между рендерами и запускает новый рендер при вызове setter с другим значением, обеспечивая реактивное отображение актуального состояния в JSX-выводе компонента. Хук useState — основа управления состоянием React для простых, ограниченных компонентом значений: полей форм, переключателей, счётчиков и флагов загрузки. Вы можете вызывать useState несколько раз в одном компоненте для управления независимыми частями состояния; поскольку хук должен вызываться на верхнем уровне — никогда внутри условий или циклов, — React надёжно отслеживает состояние в одном порядке при каждом рендере. Комбинация useState с useEffect и useContext покрывает подавляющее большинство потребностей в состоянии типичного frontend-приложения React.

Как это работает

useState строится на useState для локального состояния компонента и useEffect для сайд-эффектов (мутации DOM, подписки, сеть). useState(initial) возвращает [value, setValue]; вызов setValue(next) планирует ререндер. useEffect(fn, deps) запускает fn после рендера при изменении любого элемента deps; возврат функции из fn регистрирует cleanup. Хуки должны вызываться в одном и том же порядке каждый рендер — никогда внутри if или циклов.

Когда применять

useState — для состояния одного компонента (toggle, поля формы, hover). Поднимайте state к ближайшему общему предку, когда двум компонентам нужно его делить. useEffect — для сайд-эффектов (подписки, синк, фетч), не для производных значений (считайте их inline) или трансформации props (делайте на рендере). Пустой deps=[] запускает один раз на mount; пропущенные deps — эффект на каждый рендер (почти всегда ошибка).

Типичные ошибки

Ловушки useState: stale closures (setCount(count + 1) ловит count этого рендера — используйте setCount(c => c + 1)); пропущенные deps и эффекты на каждый рендер; чрезмерный useEffect для того, что React делает сам (computed values, зеркалирование props); неверный cleanup (подписка осталась = утечка памяти при unmount). Прочтите гайд "You Might Not Need an Effect" — он убирает половину useEffect в реальных кодовых базах.

Связанные понятия

Полезные ресурсы