Что такое состояние
Состояние (state) — это данные, которые меняются во времени и влияют на отображение. Когда состояние меняется, React перерисовывает компонент.
Состояние vs пропсы
Пропсы — входные данные. Приходят от родителя. Компонент не может их менять.
Состояние — внутренние данные. Компонент сам управляет ими.
function Counter({ initial }: { initial: number }) {
const [count, setCount] = useState(initial);
return (
<>
<p>Начальное: {initial}</p>
<p>Текущее: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</>
);
}
initial — пропс, меняется только родителем. count — состояние, меняется компонентом.
Локальное состояние
Локальное состояние живёт внутри одного компонента. Другие компоненты о нём не знают.
function SearchInput() {
const [query, setQuery] = useState('');
return <input value={query} onChange={(e) => setQuery(e.target.value)} />;
}
query не нужен никому, кроме этого input. Локальное состояние.
Состояние и рендер
React вызывает компонент при каждом изменении стейта или пропсов. Рендер — это вызов функции компонента, которая возвращает JSX.
function Component() {
const [count, setCount] = useState(0);
console.log('render');
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
Каждый клик вызывает setCount, затем React перерисовывает компонент, и console.log срабатывает снова.
Состояние неизменяемо
Стейт нельзя мутировать — только заменять.
// Плохо
items.push('новый');
setItems(items);
// Хорошо
setItems([...items, 'новый']);
React сравнивает старое и новое значение по ссылке. Если ссылка та же — он не поймёт, что что-то изменилось.
Батчинг
Несколько вызовов setState в одном обработчике объединяются в один рендер:
function handleClick() {
setCount(count + 1);
setName('Новое');
setActive(true);
// один рендер вместо трёх
}
Это делает React. Не нужно оптимизировать вручную.
Где хранить состояние
- Локально — если данные нужны только компоненту
- В родителе — если нужны нескольким детям
- В контексте — если нужны глубоко в дереве
- В сторе (Redux, Zustand) — если нужны глобально
Правило: держи состояние как можно ближе к тому месту, где оно используется.
Итоги
- Состояние — данные, меняющиеся во времени
- Изменение вызывает ререндер
- Стейт неизменяем — заменяй, а не мутируй
- Локальное состояние — внутри компонента
- Несколько
setStateбатчатся