Ваш перший компонент

Компоненти є одним з основних понять React. Вони є основою, на якій ви будуєте інтерфейси користувача (UI), що робить їх ідеальним місцем для початку вашої подорожі з React!

  • Що таке компонент
  • Яку роль відіграють компоненти у React-застосунку
  • Як написати свій перший React-компонент

Компоненти: Будівельні блоки інтерфейсу користувача

В Інтернеті HTML дозволяє створювати багаті структуровані документи за допомогою вбудованого набору тегів, таких як <h1> та <li>:

<article>
  <h1>My First Component</h1>
  <ol>
    <li>Components: UI Building Blocks</li>
    <li>Defining a Component</li>
    <li>Using a Component</li>
  </ol>
</article>

Ця розмітка представляє цю статтю <article>, її заголовок <h1> та (скорочений) зміст у вигляді впорядкованого списку <ol>. Подібна розмітка у поєднанні з CSS для стилю та JavaScript для інтерактивності лежить в основі кожної бічної панелі, аватара, модального вікна, випадаючого списку - кожного елемента інтерфейсу, який ви бачите в Інтернеті.

React дозволяє вам об'єднувати розмітку, CSS та JavaScript у кастомні "компоненти", багаторазові елементи інтерфейсу для вашого застосунку. Код змісту, який ви бачили вище, можна перетворити на <TableOfContents /> компонент, який ви можете відображати на кожній сторінці. Під капотом він використовує ті самі HTML-теги, що й <article>, <h1> і т.д.

Так само, як і у випадку з тегами HTML, ви можете компонувати, впорядковувати та вкладати компоненти для створення цілих сторінок. Наприклад, сторінка документації, яку ви читаєте, складена з React-компонентів:

<PageLayout>
  <NavigationHeader>
    <SearchBar />
    <Link to="/docs">Docs</Link>
  </NavigationHeader>
  <Sidebar />
  <PageContent>
    <TableOfContents />
    <DocumentationText />
  </PageContent>
</PageLayout>

У міру зростання вашої програми ви помітите, що багато з ваших конструкцій можна скласти, повторно використовуючи вже написані вами компоненти, що пришвидшить вашу розробку. Наш зміст вище можна додати на будь-який екран за допомогою <TableOfContents />! Ви навіть можете запустити свій проект з тисячами компонентів, якими ділиться спільнота React з відкритим вихідним кодом, таких як Chakra UI та Material UI.

Визначення компонента

Традиційно при створенні веб-сторінок веб-розробники розмічали їх вміст, а потім додавали взаємодію, додаючи трохи JavaScript. Це чудово працювало, коли взаємодія була приємним доповненням до веб-сторінок. Зараз вона є очікуваною для багатьох сайтів та всіх застосунків. React ставить інтерактивність на перше місце, використовуючи ту ж саму технологію: компонент React - це функція JavaScript, яку ви можете посипати розміткою. Ось як це виглядає (ви можете редагувати приклад нижче):

export default function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3Am.jpg"
      alt="Katherine Johnson"
    />
  )
}
img { height: 200px; }

А ось як зібрати компонент:

Крок 1: Експорт компонента

Префікс export default - це стандартний синтаксис JavaScript (не специфічний для React). Він дозволяє вам позначити основну функцію у файлі, щоб ви могли пізніше імпортувати її з інших файлів. (Більше про імпорт у Імпорт та експорт компонентів!)

Крок 2: Визначення функції

За допомогою function Profile() { } ви визначаєте функцію JavaScript з іменем Profile.

React-компоненти - це звичайні JavaScript-функції, але їхні імена повинні починатися з великої літери інакше вони не працюватимуть!

Крок 3: Додавання розмітки

Компонент повертає тег <img /> з атрибутами src та alt. <img /> написано як HTML, але насправді за лаштунками це JavaScript! Цей синтаксис називається JSX, і він дозволяє вбудовувати розмітку всередину JavaScript.

Оператори повернення можна писати в одному рядку, як у цьому компоненті:

return <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />;

Але якщо ваша розмітка не знаходиться на одному рядку з ключовим словом return, ви повинні взяти його у пару круглих дужок:

return (
  <div>
    <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
  </div>
);

Без круглих дужок будь-який код у рядках після return буде проігноровано!

Використання компонента

Тепер, коли ви визначили компонент Profile, ви можете вкласти його всередину інших компонентів. Наприклад, ви можете експортувати компонент Gallery, який використовує декілька компонентів Profile:

function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
img { margin: 0 10px 10px 0; height: 90px; }

Що бачить браузер

Зверніть увагу на різницю в обгортці:

  • <section> у нижньому регістрі, тому React знає, що ми посилаємося на HTML-тег.
  • <Profile /> починається з великої літери P, тому React знає, що ми хочемо використовувати наш компонент з назвою Profile.

А Profile містить ще більше HTML: <img />. Врешті-решт, ось що бачить браузер:

<section>
  <h1>Amazing scientists</h1>
  <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
  <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
  <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</section>

Вкладеність та організація компонентів

Компоненти є звичайними функціями JavaScript, тому ви можете зберігати декілька компонентів в одному файлі. Це зручно, коли компоненти відносно невеликі або тісно пов'язані один з одним. Якщо цей файл стає переповненим, ви завжди можете перемістити Profile в окремий файл. Ви дізнаєтеся, як це зробити, незабаром на сторінці про імпорт.

Оскільки компоненти Profile зображуються всередині Gallery - навіть декілька разів! - можна сказати, що Gallery є батьківським компонентом, який зображує кожен Profile як "дочірній". Це частина магії React: ви можете визначити компонент один раз, а потім використовувати його скільки завгодно разів і де завгодно.

Компоненти можуть рендерити інші компоненти, але ви ніколи не повинні вкладати їх визначення:

export default function Gallery() {
  // 🔴 Never define a component inside another component!
  function Profile() {
    // ...
  }
  // ...
}

Наведений вище фрагмент є дуже повільним і спричиняє вади. Натомість визначте кожен компонент на верхньому рівні:

export default function Gallery() {
  // ...
}

// ✅ Declare components at the top level
function Profile() {
  // ...
}

Коли дочірній компонент потребує даних від батьківського, передавайте їх через пропси замість визначень вкладеності.

Компоненти вниз

Ваш React-застосунок починається з "кореневого" компонента. Зазвичай, він створюється автоматично, коли ви починаєте новий проект. Наприклад, якщо ви використовуєте CodeSandbox або фреймворк Next.js, кореневий компонент визначений у pages/index.js. У цих прикладах ви експортували кореневі компоненти.

Більшість React-застосунків використовують компоненти до самого низу. Це означає, що ви будете використовувати компоненти не тільки для багаторазового використання, як кнопки, але й для більших елементів, таких як бічні панелі, списки і, зрештою, цілі сторінки! Компоненти - це зручний спосіб організувати код інтерфейсу користувача і розмітку, навіть якщо деякі з них використовуються лише один раз.

Фреймворки на основі React йдуть ще далі. Замість того, щоб використовувати порожній HTML-файл і дозволити React "взяти на себе" керування сторінкою за допомогою JavaScript, вони також генерують HTML автоматично з ваших React-компонентів. Це дозволяє вашому застосунку показувати деякий зміст до завантаження JavaScript-коду.

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

Ви щойно отримали свій перший досвід роботи з React! Давайте повторимо деякі ключові моменти.

  • React дозволяє створювати компоненти, елементи інтерфейсу користувача для вашого застосунку, які можна використовувати повторно.

  • У React-застосунку кожен фрагмент інтерфейсу користувача є компонентом.

  • Компоненти React є звичайними функціями JavaScript, окрім:

    1. Їхня назва завжди починається з великої літери.
    2. Вони повертають розмітку JSX.

Експортувати компонент

Ця пісочниця не працює, оскільки кореневий компонент не експортовано:

function Profile() {
  return (
    <img
      src="https://i.imgur.com/lICfvbD.jpg"
      alt="Aklilu Lemma"
    />
  );
}
img { height: 181px; }

Спробуйте виправити самостійно, перш ніж дивитися рішення!

Додайте експорт за замовчуванням перед визначенням функції, наприклад так:

export default function Profile() {
  return (
    <img
      src="https://i.imgur.com/lICfvbD.jpg"
      alt="Aklilu Lemma"
    />
  );
}
img { height: 181px; }

Вам може бути цікаво, чому написання export недостатньо для виправлення цього прикладу. Ви можете дізнатися про різницю між export та export default у Імпорт та експорт компонентів.

Виправлено інструкцію повернення

Щось не так у цьому операторі return. Чи можете ви це виправити?

Під час спроби виправити це, ви можете отримати помилку "Неочікувана лексема". У такому разі перевірте, чи крапка з комою з'являється після закриваючої дужки . Залишення крапки з комою всередині return ( ) призведе до помилки.

export default function Profile() {
  return
    <img src="https://i.imgur.com/jA8hHMpm.jpg" alt="Katsuko Saruhashi" />;
}
img { height: 180px; }

Ви можете виправити цей компонент, перемістивши оператор return на один рядок, наприклад:

export default function Profile() {
  return <img src="https://i.imgur.com/jA8hHMpm.jpg" alt="Katsuko Saruhashi" />;
}
img { height: 180px; }

Або обгорнувши JSX-розмітку, що була повернена, у круглі дужки, які відкриваються одразу після return:

export default function Profile() {
  return (
    <img 
      src="https://i.imgur.com/jA8hHMpm.jpg" 
      alt="Katsuko Saruhashi" 
    />
  );
}
img { height: 180px; }

Виправлено помилку

Щось не так з оголошенням та використанням компонента Profile. Чи можете ви виявити помилку? (Спробуйте згадати, як React відрізняє компоненти від звичайних HTML-тегів!)

function profile() {
  return (
    <img
      src="https://i.imgur.com/QIrZWGIs.jpg"
      alt="Alan L. Hart"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <profile />
      <profile />
      <profile />
    </section>
  );
}
img { margin: 0 10px 10px 0; height: 90px; }

Назви React-компонентів повинні починатися з великої літери.

Змінити function profile() на function Profile(), а потім змінити кожен <profile /> на <Profile />:

function Profile() {
  return (
    <img
      src="https://i.imgur.com/QIrZWGIs.jpg"
      alt="Alan L. Hart"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
img { margin: 0 10px 10px 0; }

Власний компонент

Напишіть компонент з нуля. Ви можете дати йому будь-яке ім'я і повернути будь-яку розмітку. Якщо у вас закінчилися ідеї, ви можете написати компонент Congratulations, який показує <h1>Good job!</h1>. Не забудьте його експортувати!

// Write your component below!
export default function Congratulations() {
  return (
    <h1>Good job!</h1>
  );
}