Модуль 34

Створення власних UI-компонентів

Ось готовий урок, створений за твоїм майстер-промптом. Я використав синтаксис, схожий на React/JSX, оскільки це сьогоднішній стандарт де-факто для пояснення компонентного підходу, але пояснення залишив універсальними.


🎓 Урок: Створення власних UI-компонентів

(CS50 Style Edition)


1. 🔥 Вступ: Проблема «Копіпасти»

Уявіть, що ви працюєте над сайтом для великого інтернет-магазину. Дизайнер намалював красиву кнопку: синю, з заокругленими кутами, тінню і білим текстом.

Ви, як старанний розробник, пишете HTML і CSS для цієї кнопки. Далі ви бачите, що таких кнопок на сайті — 200 штук. «Купити», «Увійти», «Детальніше», «Підписатися»…

Ви копіюєте код 200 разів. Все працює. Ви йдете пити каву. ☕️

І тут дзвонить замовник:

"Слухай, ми провели ребрендинг. Нам тепер потрібні не сині кнопки, а червоні. І кути не круглі, а квадратні. Це ж швидко, так? Просто зміни колір."

🥶 Відчули цей холод по спині? Вам тепер треба знайти всі 200 місць у коді і виправити їх вручну. А що, якщо ви пропустите одну? А що, якщо завтра вони захочуть змінити розмір шрифту?

Риторичне питання: Хіба інженери будують машини, виточуючи кожне колесо окремо з нуля? Ні. Вони беруть стандартне колесо і ставлять його на 4 різні осі.

Сьогодні ми навчимося робити те саме в коді. Ми перестанемо писати HTML-сторінки як довгі простирадла тексту і почнемо збирати інтерфейси, як конструктор LEGO.


2. 🧠 Теоретична база: Що таке Компонент?

Давайте відкинемо складні терміни.

Якщо дивитися «під капотом», то UI-компонент — це просто функція.

Згадайте математику зі школи: f(x) = y. Ви кидаєте в функцію x (дані), а вона повертає y (результат).

У розробці інтерфейсів це працює так само: 1. Ви кидаєте в функцію дані (наприклад, текст "Купити" і колір "blue"). 2. Функція повертає вам готовий шматок UI (HTML-код).

Ключові поняття (запам'ятати!):

  • Компонент (Component): Це ваша «фабрика» або «штамп». Це код, який описує, як виглядає елемент. Ви пишете його один раз.
  • Екземпляр (Instance): Це конкретний відбиток штампа на сторінці. Ви можете використати компонент 100 разів.
  • Пропси (Props/Properties): Це налаштування. Це те, чим одна кнопка відрізняється від іншої (текст, колір, іконка).

Інтуїтивна аналогія: Уявіть собі печатку (штамп). * Якщо печатка звичайнісінька — вона завжди друкує одне й те саме слово "ЗАТВЕРДЖЕНО". Це компонент без пропсів. * А тепер уявіть датер (печатку, де можна крутити коліщатка і змінювати дату). Конструкція та сама, механізм той самий, чорнило те саме, але результат (дата) кожного разу різний залежно від того, як ви накрутили коліщатка. * Датер — це Компонент. * Налаштування дати — це Props. * Відбиток на папері — це UI, який бачить користувач.


3. 🧪 Приклади (від «Hello World» до реальності)

Для прикладів використаємо псевдокод, схожий на React, бо він найбільш читабельний.

Рівень 1: Найпростіший компонент

У нас є задача: виводити привітання.

// Визначення компонента
function Welcome() {
  return <h1>Привіт, студенте!</h1>;
}

// Використання
<Welcome />
<Welcome />

Питання до вас: Що ми побачимо на екрані? (Пауза для роздумів) Ми побачимо два абсолютно однакових написи "Привіт, студенте!". Це корисно? Не дуже. Це як печатка, що не змінюється.


Рівень 2: Додаємо динаміку (Props)

Давайте зробимо наш компонент «розумним». Ми передамо йому ім'я.

// props — це об'єкт з налаштуваннями
function Welcome(props) {
  return <h1>Привіт, {props.name}!</h1>; // Підставляємо значення
}

// Використання
<Welcome name="Девід" />
<Welcome name="Марія" />

Тепер наш «завод» випустив два різні заголовки, використовуючи одне креслення.


Рівень 3: Реальний приклад — Та Сама Кнопка 🔘

Повернемося до нашої проблеми з вступу. Створимо універсальну кнопку.

function Button(props) {
  // Ми визначаємо стиль один раз тут!
  const style = {
    backgroundColor: props.color, // колір динамічний!
    borderRadius: "8px",          // всі кнопки заокруглені
    padding: "10px 20px",
    color: "white",
    border: "none"
  };

  return (
    <button style={style}>
      {props.text}
    </button>
  );
}

// Використання в реальному житті:
<Button text="Увійти" color="blue" />
<Button text="Видалити" color="red" />

Чому це круто? Якщо завтра дизайнер скаже: "Всі кнопки мають бути квадратними!", ви підете у функцію Button, зміните borderRadius: "8px" на "0px", і це автоматично застосується до всіх кнопок на сайті. Магія? Ні, це інженерія.


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

Час закачати рукави. Уявіть, що ви працюєте в редакторі коду.

Завдання 1. «Копія» Напишіть компонент Avatar, який приймає пропс imageSrc і повертає тег <img> з цим джерелом.

Завдання 2. «Умова» У вас є компонент StatusBadge(props). * Якщо props.isOnline дорівнює true, він має показувати текст "В мережі" (зеленим кольором). * Якщо false — "Офлайн" (сірим). * Підказка: Використовуйте if або тернарний оператор всередині компонента.

Завдання 3. «Виправ помилку» Розробник-початківець написав такий код:

function UserCard(props) {
  return (
    <div class="card">
      <h2>Ім'я користувача</h2> {/* Помилка тут! */}
    </div>
  )
}
// Виклик: <UserCard name="Олег" />

Чому на екрані завжди пише "Ім'я користувача", а не "Олег"? Виправте код.

Завдання 4. «Композиція (Трохи складніше)» Створіть компонент ProductCard. Він має використовувати всередині себе: 1. Ваш компонент Avatar (для фото товару). 2. Ваш компонент Button (для кнопки "Купити"). 3. І виводити ціну текстом. Це називається вкладеністю компонентів.

Завдання 5. Кейс «А що, якщо...» Що, якщо ми забули передати пропс text у нашу кнопку? <Button color="blue" />. Що покаже кнопка? Вона буде порожньою і вузькою. Як цьому запобігти? (Подумайте про значення за замовчуванням).


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

Як відрізнити новачка від профі, дивлячись на їхні компоненти?

1. Принцип єдиної відповідальності (Single Responsibility)

Новачок: Робить "Супер-Мега-Компонент", який показує хедер, потім список товарів, а потім ще й футер. Профі: Розбиває це на три компоненти: <Header />, <ProductList />, <Footer />. Порада: Якщо ваш компонент займає більше 100-150 рядків коду — ймовірно, його треба розпиляти на менші шматки.

2. Хардкод — це зло

Новачок: Пише background-color: blue прямо в CSS компонента, який має бути універсальним. Профі: Дозволяє передати колір через пропс або використовує класи primary, secondary.

3. Назви мають значення

Не називайте компонент MyBox. Називайте його PriceCard або UserProfile. Назва має говорити, що це, а не як воно виглядає.

Головна мантра: "Пиши код так, щоб його було легко видалити або замінити". Компоненти — це змінні запчастини.


6. 🧩 Підсумок

Отже, що ми сьогодні зробили? Ми перейшли від ремісництва (кожен елемент вручну) до промислового виробництва (стандартизовані деталі).

Тепер ви вмієте: 1. Створювати шаблони (компоненти) для елементів інтерфейсу. 2. Робити їх динамічними за допомогою пропсів (параметрів). 3. Економити купу часу на підтримці коду в майбутньому.

Що далі? Зараз наші компоненти красиві, але "дурні". Кнопка малюється, але що відбувається, коли ми на неї натискаємо? Як змусити кнопку відкривати меню або додавати товар у кошик? Про це — на наступному уроці: «Події та Стейт (State): Як оживити інтерфейс».

А поки — спробуйте побудувати з компонентів сторінку про себе! 🚀