Хук useState: состояние и повторные рендеры
Вызывайте useState, чтобы добавить компоненту локальное состояние, обновляйте его функцией-сеттером и разбирайтесь, когда и почему React выполняет повторный рендер.
«Хук useState: состояние и повторные рендеры» — бесплатный урок Frontend Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.
Что такое состояние?
Состояние — это данные, которые меняются со временем и при изменении должны обновлять пользовательский интерфейс. В отличие от обычных переменных, изменения состояния заставляют React повторно отобразить компонент с новым значением.
Синтаксис useState
useState(initialValue) возвращает кортеж: текущее значение и функцию-установщик. Сразу выполните его деструктуризацию.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // initial value: 0
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
);
}TypeScript: типизация useState
TypeScript выводит тип из начального значения. Если начальное значение неоднозначно — например, равно null или является пустым массивом, — добавьте явный параметр типа.
const [count, setCount] = useState(0); // inferred: number
const [name, setName] = useState(''); // inferred: string
const [user, setUser] = useState<User | null>(null); // explicit
const [items, setItems] = useState<string[]>([]); // explicitПовторное отображение при изменении состояния
Вызов функции-установщика планирует повторное отображение. React снова вызывает функцию компонента с новым значением состояния. Возвращённый JSX заменяет предыдущий результат в виртуальном DOM.
Обновления состояния выполняются асинхронно
Обновления состояния группируются и применяются перед следующим отображением, а не сразу. Не считывайте обновлённое состояние в том же обработчике события: новое значение станет доступно только при следующем отображении.
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
console.log(count); // still 0 — update hasn't applied yet
}Функциональные обновления
Если новое состояние зависит от предыдущего, используйте функциональную форму функции-установщика. Это предотвращает ошибки из-за устаревших замыканий.
// Risky (stale closure in async callbacks):
setCount(count + 1);
// Safe (functional update):
setCount(prev => prev + 1);
// Important for buttons that fire rapidly:
function increment() {
setCount(c => c + 1); // always uses the latest value
}Состояние с объектами
Если состояние является объектом, всегда создавайте новый объект — не изменяйте существующий. React сравнивает объекты по ссылке, поэтому изменения не вызовут повторное отображение.
const [user, setUser] = useState({ name: 'Alice', age: 30 });
// WRONG: mutates state — React won't re-render
user.age = 31;
setUser(user); // same reference!
// CORRECT: new object
setUser({ ...user, age: 31 });Несколько переменных состояния
Вызывайте useState несколько раз для независимых переменных состояния. Это понятнее, чем один большой объект состояния, если значения не изменяются одновременно.
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [error, setError] = useState<string | null>(null);
const [loading, setLoading] = useState(false);Ленивая инициализация
Если для начального состояния нужны затратные вычисления, передайте функцию в useState. Она выполнится только при первом отображении, а не при каждом повторном.
// Runs getInitialState() on every render (bad if expensive):
const [state, setState] = useState(getInitialState());
// Lazy init: only runs once:
const [state, setState] = useState(() => getInitialState());Когда не следует использовать состояние
Не каждой переменной нужно быть состоянием. Вычисляемые значения (total = items.reduce(…)) следует вычислять во время отображения, а не хранить в состоянии. Состояние, полученное из свойств, обычно указывает на избыточное усложнение.
Поднятие состояния
Если двум соседним компонентам нужно совместно использовать состояние, поднимите его в общего предка и передавайте вниз как свойства. Это основной шаблон управления состоянием в React до перехода к контексту или хранилищу.
Быстрая проверка
Почему следует использовать функциональную форму setCount(prev => prev + 1), а не setCount(count + 1)?
Итоги: useState
useState возвращает [значение, установщик]. Начальное значение задаёт тип, либо можно использовать явный обобщённый тип. Установщик запускает повторное отображение. Используйте функциональные обновления, когда новое состояние зависит от старого. Для объектов всегда создавайте новые объекты с помощью оператора расширения и никогда не изменяйте их напрямую. Используйте ленивую инициализацию для затратных вычислений. Поднимайте состояние к общим предкам, когда соседним компонентам нужно совместно его использовать.
Часто задаваемые вопросы
Урок «Хук useState: состояние и повторные рендеры» бесплатный?
Да — полный текст урока «Хук useState: состояние и повторные рендеры» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.
Чему я научусь в уроке «Хук useState: состояние и повторные рендеры»?
Вызывайте useState, чтобы добавить компоненту локальное состояние, обновляйте его функцией-сеттером и разбирайтесь, когда и почему React выполняет повторный рендер. Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Frontend Academy?
Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Хук useState: состояние и повторные рендеры»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Frontend Academy?
Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- JSX: синтаксис и транспиляция
- Функциональные компоненты и props
- Хук useState: состояние и повторные рендеры
- Списки, ключи и условный рендеринг