Модуль 7

Компоненти та повторне використання UI

Ось урок, створений спеціально для тебе, у стилі CS50. Вмикай уяву, ми починаємо!


🎓 Тема: Компоненти та повторне використання UI

(або "Як перестати копіювати код і почати жити")


1. 🔥 Вступ: проблема та мотивація

Уявіть, що ви працюєте в команді, яка створює Instagram. Ваша задача — зверстати стрічку новин.

Ви дивитесь на дизайн: там є пост. У поста є аватарка, нікнейм, саме фото, кнопки "лайк", "коментувати" та "поширити". Ви пишете HTML та CSS для одного поста. Виглядає чудово! 🎉

Але стривайте... В стрічці не один пост. Їх тисячі. Що ви будете робити? Копіювати цей шматок коду (HTML) 1000 разів?

А тепер уявіть найстрашніше:

Дизайнер каже: "Слухай, а давай зробимо кнопку 'лайк' не червоною, а фіолетовою? І пересунемо її вправо."

Якщо ви скопіювали код 1000 разів, вам доведеться внести 1000 правок вручну. Це пекло. Це неефективно. Це саме те, чого ми, як інженери, уникаємо.

Аналогія з життя: Уявіть, що ви будуєте будинок з LEGO. Ви ж не виплавляєте кожен пластиковий кубик з нафти щоразу, коли хочете поставити стіну? Ні! Ви берете стандартні деталі (кубики 2x4, пластини, вікна) і збираєте з них щось унікальне.

Сьогодні ми навчимося створювати власні "кубики LEGO" для інтерфейсів. Ми називаємо їх Компонентами.


2. 🧠 Теоретична база (без нудних лекцій)

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

Компонент — це незалежний шматок інтерфейсу (код + вигляд), який можна використовувати багаторазово в різних місцях програми.

Як це працює "під капотом"?

Уявіть компонент як функцію. * У математиці функція f(x) = x + 2 бере число, щось з ним робить і віддає результат. * У розробці інтерфейсів (React, Vue, Angular) компонент — це функція, яка: 1. Бере дані (наприклад, текст кнопки або посилання на картинку). Ми називаємо їх Props (властивості). 2. Повертає шматок UI (HTML-код).

Що треба запам’ятати залізобетонно: 1. Ізоляція: Те, що відбувається всередині компонента (наприклад, його стилі), не повинно ламати все інше на сторінці. 2. Параметризація (Props): Компонент має бути гнучким. Кнопка не має містити текст "Купити" всередині себе намертво. Вона має приймати текст як параметр, щоб ви могли зробити і кнопку "Купити", і кнопку "Увійти", використовуючи один і той самий код.

Інтуїтивне розуміння: Компонент — це як штамп. Ви вирізали його один раз, вмокнули в чорнило (передали дані) і можете ставити відбитки де завгодно і скільки завгодно.


3. 🧪 Приклади (від простого до реального)

Давайте подивимось на код. Я буду використовувати синтаксис, схожий на JSX (React), бо він найпопулярніший, але логіка єдина для всіх.

Приклад 1: Поганий підхід (Без компонентів)

Ми хочемо дві кнопки на сайті.

<!-- Кнопка 1 -->
<button style="background: blue; color: white; padding: 10px; border-radius: 5px;">
  Надіслати
</button>

<!-- ... десь в іншому місці ... -->

<!-- Кнопка 2 -->
<button style="background: blue; color: white; padding: 10px; border-radius: 5px;">
  Скасувати
</button>

Питання до вас: Якщо ми захочемо змінити закруглення кутів (border-radius) на 10px, у скількох місцях доведеться правити код? Правильно: у двох. А якщо кнопок 50? Отож.

Приклад 2: Створюємо компонент MyButton

Давайте створимо наш "штамп".

// Визначення компонента
function MyButton(props) {
  // props.text — це змінна частина
  return (
    <button style="background: blue; color: white; padding: 10px; border-radius: 5px;">
      {props.text}
    </button>
  );
}

Тепер використання:

<MyButton text="Надіслати" />
<MyButton text="Скасувати" />
<MyButton text="Вхід" />

Тепер, якщо дизайнер скаже "зміни колір на червоний", ми змінимо його лише в одному місці — всередині функції MyButton. І всі три кнопки на сайті миттєво оновляться. Магія? Ні, інженерія.

Приклад 3: Реальний кейс (Картка користувача)

Ускладнимо. Нам потрібна картка юзера з фото та ім'ям.

function UserCard(props) {
  return (
    <div className="card">
      <img src={props.avatarUrl} alt="User Avatar" />
      <h3>{props.name}</h3>
      <p>{props.role}</p>
    </div>
  );
}

// Використання
<UserCard 
  name="Девід Малан" 
  role="Викладач" 
  avatarUrl="/malan.jpg" 
/>

Ми передали дані всередину, і компонент сам знає, куди їх вставити.


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

Час забруднити руки кодом!

🔹 Завдання 1: Повтори (Copy-paste with understanding)

Створи компонент Alert, який виводить повідомлення в червоній рамці. Він має приймати проп message. Приклад виклику: <Alert message="Увага! Помилка!" />

🔹 Завдання 2: Зміни умови (Додай гнучкості)

Модифікуй компонент Alert із попереднього завдання. Додай проп type. * Якщо type="error" — рамка червона. * Якщо type="success" — рамка зелена. (Підказка: використовуй if або тернарний оператор всередині стилів).

🔹 Завдання 3: Виправ помилку (Bug fix)

Новачок написав такий компонент:

function WelcomeMessage(props) {
  return <h1>Привіт, props.name!</h1>;
}

При виклику <WelcomeMessage name="Олег" /> на екрані пишеться: "Привіт, props.name!" замість "Привіт, Олег!". Чому так? Виправ код.

🔹 Завдання 4: Міні-кейс

Тобі потрібно зробити список товарів для інтернет-магазину. 1. Створи компонент ProductItem (має містити назву, ціну і кнопку "Купити"). 2. Використай цей компонент 3 рази з різними даними (наприклад: iPhone, Laptop, Mouse).

🔹 Завдання 5: А що, якщо...?

А що, якщо ми забули передати проп name у компонент UserCard? Що побачить користувач? Подумай, як зробити "значення за замовчуванням" (Default Props), щоб якщо ім'я не передали, писалося "Гість".


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

Як відрізнити новачка від профі в цій темі?

⛔️ Помилка новачка: Створювати "Супер-Мега-Компоненти". Наприклад, компонент Page, в якому 500 рядків коду, де намішано і хедер, і футер, і контент. Це не компонент, це смітник.

⛔️ Інша крайність: Робити компонент на кожен "чих". Компонент <BoldText>, який просто робить текст жирним — це надлишковість. Стандартного тегу <b> або CSS достатньо.

✅ Як думає профі (Принцип DRY - Don't Repeat Yourself): Є "Правило трьох". 1. Ви написали код один раз. Ок. 2. Ви скопіювали його другий раз. Ну, буває. 3. Ви збираєтесь копіювати третій раз? СТОП. Час виносити це в окремий компонент.

Порада: Думайте про інтерфейс як про набір коробок, вкладених одна в одну. App -> містить Header та Feed. Feed -> містить багато Post. Post -> містить Avatar, Text, LikeButton. Це називається композиція.


6. 🧩 Підсумок

Ми з вами сьогодні зробили великий крок від "написання сторінок" до "архітектури додатків".

  1. Компоненти — це будівельні блоки (як LEGO).
  2. Props — це спосіб налаштувати ці блоки (колір, текст, дані).
  3. Повторне використання економить час і нерви при змінах дизайну.

Тепер ви вмієте не просто писати код, а створювати інструменти для побудови складних систем.

👀 Тизер наступного уроку: Зараз наші компоненти "тупі" — вони просто показують те, що їм передали. Але як зробити так, щоб кнопка "Лайк" запам'ятовувала, що її натиснули, і змінювала колір? Про це ми поговоримо в темі: "State (Стан): Як оживити компоненти".

А поки що — вперед до практики! Це був CS50. 😉