React – хук useState и Обработчики событий
Полезные ссылки:
📚 1. Что такое реактивность в React?
Реактивность - это способность React автоматически перерисовывать пользовательский интерфейс при изменении данных. Когда состояние компонента меняется, React "реактивно" обновляет DOM, предоставляя новую разметку.
Важно запомнить: React-компонент - это функция, которая возвращает JSX.
⚙️ 2. Обработчик событий onClick
- Чтобы отловить событие клика на элементе (например,
div), в React используется атрибутonClick. - Ему передается функция-колбэк, которая будет запущена, когда произойдет клик.
- Эта функция действует как "слушатель события" (
event listener), который реагирует на клик.
Декларативный подход: Вместо того чтобы вручную манипулировать стилями DOM, разработчик
сосредоточен на изменении данных. Алгоритм отрисовки определяет, как разметка должна выглядеть в
зависимости от состояния.
Повесим обработчик клика на div и передадим в него колбэк с id трека:
Кликаем по тайтлу первого трэка и видим 1 в сообщении

Доступ к данным через замыкания:
- В нашем примере, функция
onClickдля каждого трека формируется в контексте этого трека. - Благодаря замыканиям, каждая такая функция "помнит"
track.idтого конкретного трека, к которому она относится, даже после завершения отрисовки. Это позволит передавать правильный идентификатор в функцию-сеттер.
🚫 3. Проблема обычных переменных
Ключевая проблема: Как сделать так, чтобы интерфейс "реагировал" на действия пользователя?
Например, менялся при клике? Обычные переменные в JavaScript для этого не подходят. Нужен
инструмент, который скажет React: "Эй, данные поменялись, перерисуй всё заново!". Этот инструмент —
хук useState.
Попробуем использовать обычную переменную для хранения состояния и просто переприсваивать её значение при клике:
Проверь в браузере. Открой консоль и кликай по трекам. Ты увидишь, что логи идут, но подсветки нет.
🤔 Почему это не работает?
-
selectedTrackId— это локальная переменная внутри функцииApp. -
Когда React отрисовывает компонент, он вызывает функцию
App, получает JSX и показывает его пользователю. -
React не может отслеживать изменения обычных JavaScript-переменных, объявленных внутри компонента (например,
let selectedTrackId = null). -
Даже если такая переменная меняется, React не узнает об этом и не перерисует компонент.
-
Почему? У React нет доступа к этим переменным. Он может только вызывать функцию компонента, но не следить за её внутренними переменными.
🧠 4. Хук useState - "ячейка памяти" React
useStateсоздает специальную ячейку памяти, за которой React может следить:
🔍 5. Как работает useState изнутри
Когда мы вызываем useState(null), происходит следующее:
- React создает
fiber node- внутренний объект для хранения состояния компонента - Сохраняет начальное значение в этот node
- Возвращает массив
[текущее_значение, функция_обновления] - При повторном рендере игнорирует начальное значение и возвращает актуальное
🧩 6. Деструктурирующее присваивание
useState возвращает массив, поэтому мы используем деструктуризацию:
Подробнее о деструктурирующем присваивании можно почитать по ссылке:
✅ 7. Визуальная обратная связь
Попытка №2. Передадим в колбэк функцию-сеттер, которую нам вернул useState:
🎉 Кликаем по тайтлам треков и видим что наш UI изменился и рамка отображается:

🔄 8. Кнопка сброса выбора
-
Чтобы сбросить выделение (например, по нажатию кнопки "Reset Selection"), достаточно вызвать setSelectedTrackId(null).
-
React сам уберет рамку, так как selectedTrackId снова станет null и не будет совпадать с track.id.
Важно: Вы не думаете о прямом изменении DOM или удалении стилей; вы просто меняете данные, а React обновляет UI.
Добавим тэг button c атрибутом onClick и передадим в него null
- Кликаем по кнопке
Reset selectionи видим, что рамка исчезает
📊 9. Визуализация процесса:

-
1: React вызывает компонент App для первой отрисовки JSX
-
2: Компонент вызывает useState(null), прося React сохранить null в ячейке памяти
-
3: React сохраняет null в fiber node, ассоциированном с компонентом
-
4: React возвращает массив [null, setData] компоненту
-
5: Компонент App возвращает JSX, который React визуализирует
-
6: Пользователь кликает по элементу, вызывается setSelectedTrackId(track.id)
-
7: Функция-сеттер обновляет значение в fiber node и просит React перерисовать компонент
-
8: React снова вызывает компонент App
-
9: useState возвращает актуальное значение из fiber node
-
10: Компонент возвращает новый JSX с учетом обновленного состояния
🎓 Ключевые выводы
useState- хук для создания реактивного состояния.useStateсоздает ячейку памяти, за которой следит React- Обычные переменные не вызывают перерисовку компонента
- set-функция - единственный способ обновить состояние компонента и вызвать перерисовку
- Замыкания позволяют обработчикам событий "помнить" свои значения
- Декларативный подход - мы описываем как интерфейс должен выглядеть в зависимости от состояния, а React сам заботится об обновлениях
- Обработчик события onClick - функция, которая запускается при клике
- Условное отображение - показываем разную разметку в зависимости от state
- Деструктурирующее присваивание -
const [value, setValue] = useState(initial)
Примечание: TypeScript ошибки можно игнорировать на данном этапе, так как они не мешают работе приложения в браузере. TypeScript работает на этапе разработки, а не в рантайме.
🏠 Домашнее задание
Цель задания: Закрепить материал по useState и созданию интерактивных React-компонентов
Задание 1
Продолжай работать в проекте с предыдущего домашнего задания.
При клике на задачу покажи alert внутри которого выведи id задачи
💡 Подсказка:
- Используй обработчик события
onClick
Итоговый результат 🚀

Задание 2
- При клике на задачу она должна визуально отличаться.
borderсделай синего цвета
💡 Подсказка:
- Храни
idвыбранной задачи(selectedTaskId) вstate
Итоговый результат 🚀

Задание 3
- Добавь кнопку "Сбросить выделение", которая должна сбрасывать цвет
borderв первоначальное состояние
Итоговый результат 🚀

Проверь себя
- ✅ useState используется корректно
- ✅ Деструктурирующее присваивание применено
- ✅ onClick работает
- ✅ Выделение задач функционирует
- ✅ Кнопка сброса работает
- ✅ React перерисовывает компонент при изменении state
React реактивно обновляет твой интерфейс!

