Приложение — это дерево компонентов. Каждый компонент получает только нужные данные и передаёт события вверх.
Сначала аналогия. Представьте матрёшку или семейное дерево. Самая большая матрёшка внутри прячет поменьше, а та — ещё меньше. Так же и приложение: одна большая «коробка» внутри содержит несколько поменьше, и каждая из них — свои. Или как семья: есть бабушка (главная), у неё дети, у детей — внуки. Кто выше в дереве, тот «старше» и раздаёт указания вниз.
А что такое «компонент»? Это одна деталь конструктора (как кирпичик Lego). Из многих таких деталей собирают целую игрушку. Одна деталь умеет делать только свою маленькую работу: показать кнопку, вывести строчку списка, нарисовать форму. Собираем детали вместе — получаем приложение TaskFlow (список задач).
Что вы узнаете
Как выглядит дерево компонентов TaskFlow
Какие данные и события есть у каждого компонента
Почему данные текут вниз, а события всплывают вверх
💡 Не пытайтесь выучить всё сразу. Читайте по шагам — каждый шаг добавит по одной детали к картинке.
Шаг 1. Дерево компонентов
Изучите схему. Каждый цвет — тип компонента.
Как читать схему. Самый верхний узел — AppShell — это «бабушка» всего приложения. От неё вниз тянутся веточки: сначала общая рамка (Layout), потом страница задач (TaskPage), а внутри неё — конкретные мелочи: форма, фильтр и список с отдельными задачами. Чем глубже вложен узел, тем он «мельче» и проще.
AppShell
Header
MainLayout
Sidebar
TaskPage
TaskForm
FilterBar
TaskList
TaskItem
TaskItem
TaskItem
Оболочка — «футляр» всего приложения Layout — общая рамка/каркас страницы Страница — готовит данные для задач Контейнер списка — просто рисует список UI-компонент — маленькая деталь (кнопка, строка)
Аналогия цветов. Цвет — это «профессия» детали. Синие (Layout) строят стены дома, зелёные (контейнер) расставляют мебель, оранжевые (UI) — это выключатели и ручки. Всех их собирает воедино футляр AppShell.
Шаг 2. Заполните шаблон
Для каждого компонента запишите: какие данные он получает и какие события может инициировать.
Контекст. Сейчас вы — как конструктор, который раздаёт каждой детали её «паспорт»: что ей дадут на вход (данные) и на что она может нажать/сигналить (события). Это и есть описание интерфейса компонента.
Аналогия из жизни. Заполнить шаблон — как описать для каждого ребёнка его связь с родителем: данные приходят в почтовый ящик ребёнка (родитель опускает туда данные — данные вниз), а события — это когда ребёнок зовёт родителя (события вверх). У каждого своя роль, и путать их нельзя.
▶️ Пошаговый разбор, что делать:
Возьмите список компонентов ниже (AppShell, Header, TaskPage и т.д.).
Для каждого подумайте: что ему нужно получить, чтобы работать (данные).
Подумайте: что он может сообщить наверх, когда пользователь что-то сделал (события).
Что увидит студент. Пока это просто текст-заготовка с пропусками. Вы сами впишете туда ответы. Правильный вариант — в Шаге 3, не подсматривайте раньше времени 😉
Подсказка. Заполните шаблон до того, как смотрите ответ ниже. Важно не запомнить, а понять логику.
Шаг 3. Проверьте себя
Сверьте свои ответы с карточками. Здесь показано, что реально получает и отдаёт каждый компонент.
Аналогия из жизни. Карточки — как почтовый ящик и звонок ребёнка в семье: входящие данные родитель опускает в почтовый ящик ребёнка (данные вниз), а исходящие события — это когда ребёнок зовёт родителя (события вверх). Обратите внимание: мелкие детали (TaskItem, TaskForm, FilterBar) сами ничего не хранят — они только показывают и сигналят наверх. Вся «кухня» сосредоточена в TaskPage.
Что важно запомнить. Заметьте: поле задачи называется completed (выполнена?), а не done. Слово done здесь зарезервировано для фильтра — чтобы показывать «все / активные / выполненные» задачи. Перепутаете — код перестанет работать.
Ключевые выводы
Правило.
TaskPage — единственный «умный» компонент. Он хранит состояние.
TaskItem не знает о сервере. Он получает готовый объект и вызывает onToggle(id).
Фильтрация происходит в TaskPage. TaskList получает уже отфильтрованный массив.
События всплывают вверх (events bubble up), данные текут вниз (data flows down).
Аналогия «почтовый ящик и звонок ребёнка». Представьте семью. Данные текут вниз — как в почтовый ящик ребёнка: родитель опускает туда данные (данные вниз). События всплывают вверх — как когда ребёнок зовёт родителя (события вверх): маленькая кнопка «готово» не меняет данные сама, а лишь зовёт родителя — «я нажата!», а умный TaskPage уже решает, что с этим делать.
Аналогия «кухня и официант». TaskPage — это кухня: там готовят (фильтруют) список задач. TaskList — официант: он не готовит, а просто относит уже готовое блюдо (отфильтрованный массив) клиенту на стол. Поэтому в TaskList написано «уже отфильтрованный!».
Интерактивная песочница
Попробуйте изменить структуру компонентов или данные:
Контекст. Ниже — живой пример на чистом JavaScript. Он показывает, как компоненты TaskItem и TaskList собирают список задач и выводят его на экран. Это упрощённая модель нашего дерева: здесь корень рисует заголовок и вызывает TaskList, а TaskList вызывает TaskItem для каждой задачи.
Аналогия из жизни. Песочница — это ваш рабочий верстак или кухонный стол для экспериментов. Хочешь — поменяй название задачи, хочешь — добавь новую строчку, хочешь — перекрась галочку. Если испортишь — ничего страшного: оригинал урока не пострадает, а ты просто нажмёшь «Запустить» и увидишь результат.
▶️ Пошаговый разбор, что делает этот код:
Данные. Создаём массив tasks — три задачи, у каждой есть id, title и поле completed (выполнена или нет).
TaskItem. Функция берёт одну задачу и возвращает готовый HTML-кусочек: зелёный фон и галочку «✓», если completed true, и серый фон с «○», если нет.
TaskList. Берёт весь список, для каждой задачи вызывает TaskItem (через .map()) и склеивает результаты в один <ul>.
Корень. Записывает в блок #app заголовок со счётчиком и собранный список. На экране появляются три задачи.
💡 Что увидит студент после нажатия «Запустить»: заголовок «Список задач (3)» и три строчки. Первая — зелёная с галочкой (выполнена), остальные — серые с кружком.
Песочница: нажми «Запустить» — и увидишь список задач TaskFlow, собранный из компонентов TaskList и TaskItem. Меняй код и запускай снова.
Песочница: дерево компонентов
Попробуйте сами. В массиве tasks поменяйте completed: false на completed: true у второй задачи и нажмите «Запустить» — строчка станет зелёной. Так вы на практике увидите, как данные (поле completed) влияют на то, что рисует компонент.