State и хуки

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

Хуки состояния — это основной React API для управления локальным состоянием компонента в функциональных компонентах: useState и useReducer являются двумя встроенными примитивами, предоставляемыми React. useState принимает начальное значение и возвращает кортеж из текущего состояния и функции-сеттера; в TypeScript обобщённая форма useState<T>(initialValue) обеспечивает строгую типизацию состояния по всему компоненту. useReducer предпочтительнее useState для сложных переходов состояния, включающих несколько связанных значений, или когда следующее состояние зависит от предыдущего, — следуя тому же паттерну редьюсера, который popularized Redux для управления состоянием. Оба хука состояния запускают перерендер React при обновлении состояния, и React батчирует несколько обновлений состояния внутри обработчиков событий (а в React 18 — также в асинхронных контекстах) для минимизации обновлений DOM и оптимизации производительности фронтенда. Совместное использование хуков состояния с контекстом (useContext) или внешними библиотеками, такими как zustand, даёт React-разработчикам полный инструментарий управления состоянием — от простого локального состояния до потоков данных уровня приложения.

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

State и хуки строится на 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 — эффект на каждый рендер (почти всегда ошибка).

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

Ловушки State и хуки: 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 в реальных кодовых базах.

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

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