Что такое состояние
Данные, которые принадлежат компоненту и меняются со временем. Введённый текст, открыт ли список, загружаются ли данные, что выбрал пользователь.
Отличие от передаваемых данных простое:
- Передаваемые данные приходят сверху и компонентом не меняются.
- Состояние живёт внутри компонента и меняется им самим.
Как объявить
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Нажато раз: {count}
</button>
);
}
Разберём: объявляем состояние с начальным значением ноль, получаем текущее значение и функцию для его изменения. При изменении компонент перерисовывается сам.
Ключевое, что надо принять: напрямую менять состояние нельзя. Только через функцию изменения. Присваивание не сработает — библиотека просто не узнает об изменении.
Изменение на основе прежнего значения
Тонкость, о которую спотыкаются: если новое значение зависит от старого, лучше передавать функцию.
setCount((prev) => prev + 1);
Причина: обновления могут объединяться, и обращение к переменной напрямую иногда даёт устаревшее значение. Через функцию всегда получаете актуальное.
Состояние с объектами и массивами
Здесь главная ловушка новичков: изменять существующий объект нельзя, надо создавать новый.
Неправильно:
notes.push(newNote);
setNotes(notes);
Правильно:
setNotes([...notes, newNote]);
Причина: библиотека сравнивает ссылки. Если ссылка та же, она считает, что ничего не изменилось, и перерисовки не произойдёт. Человек видит, что данные не обновились, и не понимает почему.
То же с объектами: создавайте новый на основе старого, а не меняйте поля существующего.
Подъём состояния
Частая ситуация: двум соседним компонентам нужны одни данные. Например, поле поиска и список результатов.
Решение: перенести состояние в их общего родителя и передать вниз — значение одному, функцию изменения другому.
Это называется подъёмом состояния и является основным приёмом организации данных. Правило простое: состояние живёт в ближайшем общем родителе тех, кому оно нужно.
Когда состояния становится много
Если данные нужны в десяти местах на разной глубине, передавать их вручную через все уровни утомительно. Тогда используют встроенный механизм передачи через контекст или отдельные библиотеки управления состоянием.
Но не начинайте с них. Сначала научитесь обходиться обычным состоянием и подъёмом: большинство учебных проектов в них не нуждается, а привычка тащить тяжёлые инструменты в простые задачи — плохая.
Ошибки, которые совершают все
Изменяют состояние напрямую. Разобрали выше. Самая частая.
Кладут в состояние то, что можно вычислить. Если значение выводится из других данных, храните исходные, а нужное считайте при отрисовке. Иначе рано или поздно рассинхронизируется.
Забывают, что изменение состояния происходит не мгновенно. Сразу после вызова функции изменения переменная содержит ещё старое значение.
Складывают всё в один большой объект состояния. Тогда любое изменение перерисовывает всё. Разделяйте по смыслу.
Как проверить, что поняли
Сделайте список задач: добавление, отметка выполнения, удаление, фильтр по состоянию. Всё на обычном состоянии, без дополнительных библиотек.
Если получилось и ничто не рассинхронизировалось — тема освоена.
Хватит читать — пора делать
На CohortX можно найти команду под пет-проект и получить тот самый опыт, о котором спрашивают на собеседовании.
Похожие статьи
- Why you need a framework on top of ReactWhat React doesn't solve, what a framework like Next.js adds, and whether a beginner should start there.
- Зачем нужен фреймворк поверх ReactКакие задачи React не решает, что добавляет надстройка вроде Next.js и стоит ли новичку браться за неё сразу.
- React: state and passing data, with examplesWhat state is, how it differs from props, how to lift it up, and the mistakes everyone makes.