Callbacks
Автор конспекта: Стогниева Виктория
👨👦 Введение: Обычный порядок вещей
Представьте компоненты как семью:
- 🎯 Родитель → управляет дочерним компонентом через пропсы
- 🔻 Стандартный поток → сверху вниз
- ❌ Проблема: дочерний компонент не может напрямую вызывать родительские функции
По правилам React, ребенок не должен зависеть от родителя на уровне кода — то есть, он не может
его импортировать и напрямую вызывать его функции. Так как же ему «позвонить» и попросить о
помощи?
📱 Решение: "телефончик" для дочернего компонента
Этот телефончик — это специальная функция, которую мы передаем из родительского компонента в
дочерний. Эта функция называется колбэк-функция (от англ. callback — обратный вызов).
Аналогия с setTimeout:
В React:
- 📞 Колбэк-функция → это "телефончик"
- 🔄 Родитель передает функцию через пропсы
- 📢 Ребенок вызывает функцию когда нужно
⚡ Как это работает: два подхода
🎯 Прямое управление (стандартный поток):

- Зависимость: Родитель → Ребенок (импорт через
import) - Управление: Родитель → Ребенок (родитель вызывает функции ребенка)
🔄 Инверсия управления (с колбэком):

- Зависимость: Родитель → Ребенок
- Управление: Ребенок → Родитель (ребенок вызывает колбэк)
Инверсия управления (Inversion of Control, IoC) — это архитектурный паттерн, при котором объект, от которого мы зависим, начинает управлять нами, а не как обычно — мы им.
🎮 Практический пример: игра "Счетчик до пяти"
Цель игры:
- Есть родительский компонент
Game, который решает, что показывать на экране: счетчик или картинку со слоником. - Есть дочерний компонент
Counter, который считает клики по кнопке до 5. - Когда
Counterдосчитает до 5, он должен сообщитьGame, чтобы тот показал слоника.
Решение:
- Шаг 1: родительский компонент
Game. Родительский компонентGame— это наш «информационный эксперт». Он отвечает за общую логику игры и хранит в своем состоянии, какая «страница» сейчас активна: счетчик или слоник.
-
Шаг 2: передача "телефончика" ().
Gameсоздает функциюhandleFinish, которая меняет страницу на слоника, и передает ее вCounterчерез пропonFinish. Эта функция и есть наш «телефончик». -
Шаг 3: работа ребенка (). Компонент
Counterабсолютно самодостаточен. Он имеет свое внутреннее состояние для счетчика и ничего не знает ни оGame, ни о слониках. Его единственная задача — считать до пяти. Когда счетчик достигает нужного значения, он проверяет, передали ли ему «телефончик»(props.onFinish). Если да — он «звонит».
- Шаг 4: дочерний компонент
Elephant
🎯 Результат:
- Пользователь кликает 5 раз
Counterвидит, что счетчик равен 5Counterвызываетprops.onFinish()- Этот «звонок» активирует функцию
handleFinishвнутри компонентаGame handleFinishменяет состояниеactivePageна'elephant'.- Компонент
Gameперерисовывается,Counterисчезает, а на его месте появляется слоник.🐘
Почему это так важно?
Главный принцип, который мы здесь соблюдаем, — это принцип информационного эксперта. Каждый компонент должен отвечать только за свою область знаний. Инверсия управления помогает нам этого достичь.
✅ Преимущества:
- 🎯 Разделение ответственности → каждый компонент занимается своим делом
- 🔄 Переиспользуемость →
Counterможно использовать в разных местах - 📊 Предсказуемость → логика сосредоточена в одном месте
- 🛡 Принцип информационного эксперта → каждый знает только о своей зоне ответственности
❌ Чего НЕ делать:
Итак, инверсия управления через колбэки — это простой, но невероятно мощный прием. Это как дать дочернему компоненту «телефончик» для связи с родителем, позволяя ему сообщить о важных событиях, не нарушая иерархии зависимостей.
🏠 Домашнее задание
Цель задания: Овладеть мощнейшим архитектурным принципом — инверсией управления — и научиться создавать компоненты, которые могут взаимодействовать через callback-функции.
Теоретические вопросы
1. Основы инверсии управления
- Объясни своими словами, что такое инверсия управления
- В чём разница между прямым управлением и инверсией управления?
- Приведи 3 примера из жизни, где можно увидеть принцип инверсии управления (по аналогии с "телефончиком" из урока)
2. Callback функции
- Что такое callback функция и почему она называется "функцией обратного вызова"?
- Объясни на примере
setTimeout, как работает инверсия управления - Почему callback функцию передают БЕЗ круглых скобок?
3. React компоненты
- Как props помогают реализовать инверсию управления между родительским и дочерним компонентами?
- Что такое "информационный эксперт" и как правильно распределить ответственности между компонентами?
Практические задания
Задание 1
Игра про слона
Напиши код игры из видеоурока:
- Создай компоненты
Game.tsx,Counter.tsxиElephant.tsx - При клике на кнопку
+счетчик должен увеличиваться на единицу - Когда значение счетчика будет равно 5 покажи
emojiслона (🐘)
Задание 2
Будем развивать нашу игру для детей.
-
В компоненте
Counter.tsxдобавь заголовок "Нажми на кнопку 4 раза, чтобы увидеть слона", чтобы ребенок понимал что делать -
В компоненте
Elephant.tsxдобавь кнопку "Давай сыграем еще раз"
- При клике по данной кнопке игра должна вернуться на страницу счетчика
- Счётчик должен сброситься к первоначальному состоянию
Итоговый результат 🚀

Задание 3
Продолжим развивать игру.
- В компоненте
Elephant.tsxдобавь локальное состояние в котором будем хранить вес слона
- В компоненте
Elephant.tsxдобавь 2 кнопки при помощи которых ребенок будет кормить слона.
- При нажатии на первую кнопку вес слона должен увеличиваться на 20, т.к. ребенок будет кормить слона полезной едой
- При нажатии на вторую кнопку вес слона должен уменьшаться на 20, т.к. ребенок будет кормить слона вредной едой
- С каждым нажатием на кнопку слон должен пропорционально изменяться (увеличиваться или уменьшаться) в зависимости от того на какую кнопку нажимает ребенок
Итоговый результат 🚀

Задание 4
- Создай компонент
Congratulations.tsx, который нужно будет рендериться когдаweightслона станет равным или больше 200.
- В теле данного компонента напиши "🎉 Поздравляю! Твой слон наелся здоровой пищи и с улыбкой побежал играть с другими слонами🎉"
- Добавь кнопку с сообщением "Давай сыграем еще раз и покормим другого слона", которая вернет ребенка на первоначальную страницу счетчика
- Добавь радостный смайлик, чтобы ребенок обрадовался, т.к. он сделал все верно
<div style={{ fontSize: "200px" }}>😊</div>
- Создай компонент
GameOver.tsx, который нужно будет рендериться когдаweightслона станет равным или меньше 20
- В теле данного компонента напиши "У твоего слоника заболел живот и вместо того чтобы играть со своими друзьями он пошел к врачу. В следующий раз корми слона правильной пищей, чтобы слоник был здоров"
- Добавь кнопку с сообщением "Но не расстраивайся. Давай сыграем еще раз", которая вернет ребенка на первоначальную страницу счетчика
- Добавь грустный смайлик
<div style={{ fontSize:'200px'}}>🥲</div>
- В компоненте
Elephant.tsxудали кнопку "Давай сыграем еще раз", т.к. данную кнопку мы перенесли в компонентыCongratulations.tsxиGameOver.tsx
Итоговая логика такая. Если ребенок кормит слона правильной пищей, то слон растет и достигнув веса 200 ребенок видит сообщение о том что слон наелся и играет. Если ребенок кормит слона вредной пищей, то слон уменьшается и достигнув веса 20 ребенок видит сообщение, что слон пошел к врачу лечить живот
Итоговый результат 🚀

🔶 Помни: инверсия управления — это основа всех современных фреймворков и библиотек. От понимания этого принципа зависит твое архитектурное мышление как инженера.
🔶 Думай как архитектор: каждый компонент должен быть самодостаточным, но уметь "кричать" родителю о важных событиях через callback-и. Это ключ к созданию переиспользуемых компонентов.
🔶 Экспериментируй: добавляй console.log в callback-функции, наблюдай за потоком управления.
Попробуй нарушить принципы — посмотри, что сломается. Только через ошибки приходит понимание.
🔶 Удачи, самурай! Освоив инверсию управления, ты сделаешь важный шаг от "кодера" к "инженеру". Этот принцип откроет тебе дверь в серьезную архитектуру. 🥷⚡


