Модуль 8

Props: передача даних у компоненти

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


🎓 Тема: Props: передача даних у компоненти

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

Уявіть, що ви створюєте клон Instagram. У вас є стрічка новин, яка складається з тисяч постів.

Ви вже знаєте, як створити компонент <Post />. Ви пишете код, додаєте туди картинку котика, ім'я автора "Василь" і текст "Мій чудовий ранок". Ви рендерите цей компонент тричі... і що бачите?

Три однакові пости з одним і тим самим котиком і підписом.

Запитання до вас: Чи має сенс створювати 1000 різних компонентів: <PostVasyl />, <PostOksana />, <PostPetro /> для кожного користувача? Звісно, ні! Це було б божевіллям. Програмісти — люди ледачі (в хорошому сенсі), ми не любимо повторювати код (DRY — Don't Repeat Yourself).

Аналогія: Уявіть, що компонент — це форма для випікання кексів. Вона завжди має одну й ту ж структуру (метал, форма зірочки). Але те, що ви туди заливаєте — тісто з родзинками, шоколадом чи горіхами — це і є Props.

Без Props ваші компоненти — це просто статичні штампи. З Props вони стають універсальними інструментами.


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

Що ж таке Props? Це скорочення від Properties (властивості).

Якщо говорити мовою JavaScript (а React — це і є JavaScript), то все геніально просто:

Компонент — це функція. Props — це аргументи цієї функції.

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

Коли React бачить ваш код <Button label="Натисни мене" />, він робить наступне: 1. Знаходить функцію Button. 2. Збирає всі атрибути (label, color тощо) в один об'єкт. 3. Передає цей об'єкт у функцію як перший аргумент. Зазвичай ми називаємо його props.

🚨 Що треба запам'ятати (Залізне правило):

Props — це "read-only" (тільки для читання). Ви не можете змінити пропси всередині дочірнього компонента. * ✅ Батько (App) каже дитині (Post): "Ось тобі текст, покажи його". * ❌ Дитина (Post) не може сказати: "Ні, я зміню цей текст на інший".

Це називається односпрямований потік даних (Unidirectional Data Flow). Дані течуть вниз, як водоспад.


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

Приклад 1: Привітання (Hello World на стероїдах)

Давайте створимо компонент, який вітає користувача.

Без props (сумно і статично):

function Welcome() {
  return <h1>Привіт, Алісо!</h1>;
}
// Цей компонент завжди вітатиме лише Алісу.

З props (динамічно):

// 1. Приймаємо аргумент props
function Welcome(props) {
  // 2. Використовуємо дані з об'єкта props
  return <h1>Привіт, {props.name}!</h1>; 
}

// Використання:
// <Welcome name="Аліса" />  -> Привіт, Аліса!
// <Welcome name="Боб" />    -> Привіт, Боб!

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

Уявіть інтернет-магазин. Нам потрібна картка товару з назвою, ціною та статусом наявності.

Питання: Що ви очікуєте побачити в аргументах функції ProductCard?

Правильно: об'єкт, у якому будуть властивості title, price тощо.

// Використовуємо деструктуризацію (сучасний підхід)
// Замість (props) пишемо ({ title, price, inStock })
// Це дозволяє зразу витягнути потрібні змінні.

function ProductCard({ title, price, isNew }) {
  return (
    <div className="card">
      {/* Якщо товар новий, показуємо бейдж */}
      {isNew && <span className="badge">🆕 Новинка!</span>}

      <h2>{title}</h2>
      <p>Ціна: ${price}</p>

      <button>Купити</button>
    </div>
  );
}

// Як ми це викликаємо у батьківському компоненті:
export default function App() {
  return (
    <div>
      <ProductCard title="iPhone 15" price={999} isNew={true} />
      <ProductCard title="Чохол силіконовий" price={20} isNew={false} />
    </div>
  );
}

Чому результат такий? React взяв дані з <ProductCard ... /> і "впорхнув" їх у змінні всередині функції. Зверніть увагу: ми можемо передавати не тільки рядки, а й числа (999) та булеві значення (true/false).


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

Час "забруднити руки" кодом! Виконайте ці завдання по черзі.

  1. 🔹 Повторення: Створіть компонент <City name="..." country="..." />, який виводить: "Київ знаходиться в країні Україна". Перевірте його для 3 різних міст.
  2. 🔹 Зміна умов: Додайте до компонента City проп isCapital (булеве). Якщо це столиця — виведіть текст жирним шрифтом або додайте емодзі 👑.
  3. 🔹 Виправлення помилки: jsx function User(props) { // Увага! Тут помилка. Чому це не спрацює? props.name = "Супер " + props.name; return <div>User: {props.name}</div>; } Завдання: Поясніть, чому це ламає додаток, і виправте код так, щоб ім'я відображалося з префіксом "Супер", не змінюючи сам об'єкт props.
  4. 🔹 Міні-кейс (YouTube): Створіть компонент <VideoPreview />. Він має приймати:
    • Заголовок відео
    • Кількість переглядів
    • URL картинки (прев'ю)
    • Ускладнення: Якщо переглядів більше 1 млн, виводьте "🔥 Популярне".
  5. 🔹 А що, якщо... Спробуйте передати в проп не рядок і не число, а... інший компонент або HTML-тег.
    • Наприклад: <Card content={ <img src="..." /> } />.
    • Чи відобразиться це? (Спойлер: так, React дуже гнучкий!).

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

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

❌ Типова помилка новачка: "Prop Drilling" (Свердління пропсів)

Ви передаєте userName від Прадідуся -> Дідусеві -> Батьку -> Дитині, хоча проміжним компонентам це ім'я взагалі не потрібне. Порада: Якщо ви передаєте дані через 5 рівнів униз — зупиніться. Можливо, вам потрібен інший підхід (але про це пізніше, в темі Context).

✅ Як думає профі:

  1. Деструктуризація — це закон. Не пишіть props.user.name. Пишіть function Profile({ user }) і далі user.name. Код стає чистішим.
  2. Валідація. Ви завжди думаєте: "А що, якщо мені не передадуть ціну?".
    • Встановлюйте значення за замовчуванням: function Button({ color = "blue" }). Тепер, якщо колір не передали, кнопка не зламається, а буде синьою.
  3. Компоненти мають бути "чистими". Якщо ви даєте ті самі пропси, компонент завжди має виглядати однаково. Жодної магії та випадкових чисел всередині.

6. 🧩 Підсумок

Сьогодні ви зробили величезний крок. Ви перейшли від написання статичного HTML до створення динамічних архітектур.

  • Ми дізналися: Props — це спосіб передачі даних від батьків до дітей.
  • Ми зрозуміли: Props не можна змінювати (вони read-only).
  • Ми навчилися: Створювати універсальні компоненти, які можна використовувати повторно.

Тепер ви вмієте: Побудувати стрічку новин, список товарів або картки користувачів, написавши код компонента лише один раз! 🎉

🔮 Тизер наступного уроку:

Але чекайте... Props — це класно, коли дані приходять "зверху". А що робити, якщо ми хочемо натиснути кнопку "Лайк" ❤️ і змінити лічильник лайків прямо тут, у компоненті? Пропси змінювати не можна. Тоді як це зробити? Для цього нам знадобиться Пам'ять компонента — або, як ми це називаємо в React, State (Стан). Про це — наступного разу!


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