Модуль 7

Компоненти: створення та життєвий цикл

Ось готовий урок, згенерований за твоїм майстер-промптом. Я обрав контекст React.js, оскільки це найпопулярніша бібліотека для демонстрації компонентного підходу, але пояснення побудовані так, щоб зрозуміти саму філософію, яка застосовується і в Vue, і в Angular, і в Svelte.


🎓 Урок: Компоненти: створення та життєвий цикл

(Стиль: CS50 / David Malan)


1. 🔥 Вступ: Хаос проти Порядку

Уявіть, що ви будуєте будинок. Справжній хмарочос.

Якби ви підійшли до цього так, як новачки часто пишуть код, ви б спробували відлити всю будівлю — від фундаменту до антени на даху — з одного суцільного шматка бетону. Одночасно.

Звучить як божевілля, правда?

Але саме це ми робимо, коли пишемо вебсторінку як один гігантський HTML-файл на 5000 рядків. * Що станеться, якщо замовник скаже: «Зміни форму вікон на всіх 100 поверхах»? Ви будете лазити по цьому бетонному моноліту з зубилом і правити кожне вікно вручну? * А якщо ви припуститеся помилки в одному місці, чи не завалиться вся будівля?

У світі розробки ми не будуємо моноліти. Ми будуємо з блоків. Як LEGO.

Сьогодні ми поговоримо про Компоненти. Це і є ті самі цеглинки LEGO. Ми навчимося їх створювати, вдихати в них життя і... (це звучить сумно, але необхідно) правильно їх знищувати.

Тож, навіщо нам це? Щоб один раз створити деталь «Вікно», а потім використати її 1000 разів, змінюючи лише колір рами.


2. 🧠 Теоретична база: Що всередині цеглинки?

Давайте зазирнемо «під капот». Забудьте на хвилину про складний код.

Що таке компонент?

Інтуїтивно: Це шматок інтерфейсу (кнопка, картка товару, шапка сайту). Технічно (в React та багатьох інших): Це звичайна функція.

Так, серйозно. 1. Функція отримує дані (ми називаємо їх Props — як інгредієнти). 2. Функція повертає розмітку (HTML/JSX — як готова страва).

💡 Запам’ятайте обов'язково: Компонент — це завод. На вхід заїжджає сировина (дані), на вихід виїжджає готовий інтерфейс.

Життєвий цикл (Lifecycle)

Компоненти не статичні. Вони поводяться як живі організми. У кожного компонента є три фази існування:

  1. Народження (Mounting): Компонент вперше з'являється на екрані. Аналогія: Ви зайшли в кімнату. Вас побачили. Ви привіталися. Що робимо: Завантажуємо дані з сервера, запускаємо таймери.

  2. Життя / Оновлення (Updating): Компонент реагує на зміни (користувач натиснув кнопку, прийшли нові дані). Аналогія: Вам стало жарко, ви зняли куртку. Ви змінилися, але ви все ще в кімнаті. Що робимо: Перемальовуємо інтерфейс з новими даними.

  3. Смерть (Unmounting): Компонент зникає з екрану (користувач перейшов на іншу сторінку). Аналогія: Ви вийшли з кімнати. Що робимо: Дуже важливо! Прибираємо за собою. Вимикаємо таймери, скасовуємо запити. Якщо цього не зробити, це як залишити увімкнену праску в готелі, з якого ви вже виїхали. Це називається «витік пам'яті» (memory leak).


3. 🧪 Приклади: Від атома до молекули

Давайте напишемо код. Я буду використовувати синтаксис React, бо він найпопулярніший, але логіка всюди однакова.

Приклад 1: Найпростіший атом

Що ви очікуєте побачити? Просто функцію, яка повертає HTML.

// 1. Створюємо компонент (функцію)
function WelcomeButton() {
  return (
    <button style={{ backgroundColor: "blue", color: "white" }}>
      Привіт, я компонент!
    </button>
  );
}

// 2. Використовуємо його десь в додатку
// <WelcomeButton />

Пояснення: Ми створили свій власний HTML-тег <WelcomeButton />. Ми можемо вставити його 50 разів, і це буде 50 однакових кнопок.


Приклад 2: Додаємо індивідуальність (Props)

Але 50 однакових кнопок — це нудно. Давайте зробимо так, щоб кнопка «знала», що на ній написано.

function SmartButton(props) {
  // props - це об'єкт з даними, які ми передали
  return (
    <button style={{ backgroundColor: props.color }}>
      {props.text}
    </button>
  );
}

// Використання:
// <SmartButton text="Увійти" color="green" />
// <SmartButton text="Видалити" color="red" />

Чому це круто? Логіка кнопки (стилі, поведінка при наведенні) написана один раз. А контент (текст, колір) ми міняємо при використанні. Це і є перевикористання коду.


Приклад 3: Життєвий цикл у дії (useEffect)

Уявіть компонент-годинник. * Коли він з'являється (Mount), годинник має почати цокати. * Коли ми його прибираємо (Unmount), він має замовкнути.

import { useEffect } from 'react';

function Timer() {
  useEffect(() => {
    // Цей код спрацює при НАРОДЖЕННІ (Mount)
    console.log("🟢 Таймер з'явився на екрані!");

    const intervalId = setInterval(() => {
      console.log("⏰ Тік-так...");
    }, 1000);

    // Ця функція спрацює при СМЕРТІ (Unmount)
    return () => {
      console.log("🔴 Таймер зник. Прибираємо за собою.");
      clearInterval(intervalId); // Зупиняємо цокання
    };
  }, []); // Порожній масив означає: "роби це тільки при старті"

  return <div>Я — таймер. Дивись у консоль!</div>;
}

Що тут відбувається? Якщо ви приберете цей компонент з екрану, React автоматично викличе функцію очищення (clearInterval). Якби ми цього не зробили, годинник продовжував би цокати в пам'яті комп'ютера вічно, пожираючи ресурси.


4. 🛠 Практична частина

Час забруднити руки. Не бійтеся помилятися — компілятор не кусається, він просто червоніє.

Завдання 1: Копіпаст-майстер Створіть компонент Greeting, який просто виводить <h1>Привіт, Світ!</h1>. Викличте його тричі підряд.

Завдання 2: Персоналізація Змініть Greeting так, щоб він приймав проп name. * Виклик 1: <Greeting name="Олег" /> -> має вивести "Привіт, Олег!" * Виклик 2: <Greeting name="Марія" /> -> має вивести "Привіт, Марія!"

Завдання 3: «Зламай мене» Спробуйте передати name в компонент, але всередині компонента спробуйте вивести props.age (якого не існує). Що покаже браузер? (Спойлер: нічого або помилку, це важливо побачити).

Завдання 4: Реальний кейс (Міні-картка) Створіть компонент UserCard. Він має приймати avatar (посилання на картинку), username та status (онлайн/офлайн). Зверстайте це красиво (картинка зліва, текст справа).

Завдання 5: Експеримент з циклом Використайте приклад з Timer вище. Додайте кнопку, яка ховає/показує цей таймер. Відкрийте консоль браузера (F12) і переконайтеся, що ви бачите повідомлення "🔴 Таймер зник", коли приховуєте його.


5. 💡 Мислення як у розробника

Як відрізнити код новачка від коду профі, навіть якщо обидва працюють?

  1. Синдром «Божественного компонента» (God Component):

    • Новачок: Пише компонент Page, в якому 800 рядків коду: і шапка, і список товарів, і футер, і логіка авторизації.
    • Профі: Розбиває це на Header, ProductList, Footer, AuthForm. Кожен компонент робить одну річ, але робить її добре.
  2. Проблема «Зомбі-процесів»:

    • Новачок: Запускає підписку на дані або таймер при маунтінгу, але забуває очистити її при розмаунтінгу.
    • Наслідок: Користувач пішов зі сторінки, а в консолі сиплються помилки: "Can't perform state update on an unmounted component".
    • Профі: Завжди думає: «Якщо я це увімкнув, де я це вимкну?».
  3. Правило DRY (Don't Repeat Yourself): Якщо ви двічі натиснули Ctrl+C / Ctrl+V, щоб скопіювати шматок HTML — зупиніться. Це сигнал створити новий компонент.


6. 🧩 Підсумок

Отже, що ми маємо в сухому залишку?

  1. Ми більше не пишемо «сторінки». Ми створюємо систему незалежних блоків.
  2. Компонент — це просто функція: Дані (Props) -> Візуалізація (UI).
  3. Компоненти народжуються, оновлюються і помирають. Контролювати їхню смерть так само важливо, як і народження.

Що ви тепер вмієте? Ви можете розбити будь-який складний інтерфейс (наприклад, YouTube) на дрібні шматочки (відео, коментар, лайк, сайдбар) і реалізувати їх окремо.

🔍 Тизер наступного уроку: Зараз наші компоненти трохи «тупі» — вони показують лише те, що їм передали батьки (через Props). Але як змусити компонент щось запам’ятати? Наприклад, скільки разів на нього клікнули? Наступного разу ми поговоримо про State (Стан) — короткочасну пам'ять компонента. Це буде справжня магія.


Це був CS50. Побачимось! 👋