Написання розмітки з JSX

JSX — це синтаксичне розширення для JavaScript, яке дозволяє вам писати HTML-подібну розмітку всередині файлу JavaScript. Хоча існують інші способи написання компонентів, більшість розробників React віддають перевагу лаконічності JSX, і більшість кодових баз використовують його.

You will learn

  • Чому React змішує розмітку з логікою відображення
  • Чим JSX відрізняється від HTML
  • Як відображати інформацію за допомогою JSX

JSX: Вставка розмітки в JavaScript

Веб був побудований на HTML, CSS та JavaScript. Протягом багатьох років веброзробники розміщали вміст у HTML, дизайн у CSS, а логіку у JavaScript — часто у відокремлених файлах! Вміст розмічався всередині HTML, тоді як логіка сторінки мешкала окремо у JavaScript:

HTML розмітка з фіолетовим фоном та елементом div з двома дочірніми тегами: p та form.
HTML розмітка з фіолетовим фоном та елементом div з двома дочірніми тегами: p та form.

HTML

Три JavaScript обробники з жовтим фоном: onSubmit, onLogin та onClick.
Три JavaScript обробники з жовтим фоном: onSubmit, onLogin та onClick.

JavaScript

У міру зростання інтерактивності Вебу, логіка все більше впливала на вміст. JavaScript став відповідальним за HTML! Ось чому у React, логіка відображення та розмітка знаходяться разом в одному місці — компонентах.

React-компонент з HTML та JavaScript змішаних з попередніх прикладів. Функція називається Sidebar, яка викликає функцію isLoggedIn, яка виділена жовтим кольором. Вкладений всередині функції, яка виділена фіолетовим кольором, є тег p, який був показаний раніше, і тег Form, який посилається на компонент, показаний на наступній діаграмі.
React-компонент з HTML та JavaScript змішаних з попередніх прикладів. Функція називається Sidebar, яка викликає функцію isLoggedIn, яка виділена жовтим кольором. Вкладений всередині функції, яка виділена фіолетовим кольором, є тег p, який був показаний раніше, і тег Form, який посилається на компонент, показаний на наступній діаграмі.

Sidebar.js React компонент

React-компонент з HTML та JavaScript змішаних з попередніх прикладів. Назва функції - Form, яка містить два обробники подій onClick та onSubmit, які позначені жовтим кольором. Після обробників слідує HTML, який позначений фіолетовим кольором. В HTML міститься елемент форми з вкладеним елементом input, кожен з них має властивість onClick.
React-компонент з HTML та JavaScript змішаних з попередніх прикладів. Назва функції - Form, яка містить два обробники подій onClick та onSubmit, які позначені жовтим кольором. Після обробників слідує HTML, який позначений фіолетовим кольором. В HTML міститься елемент форми з вкладеним елементом input, кожен з них має властивість onClick.

Form.js React компонент

Зберігання логіки відображення кнопки та її розмітки разом гарантує, що вони залишаються синхронізованими одне з одним при кожному редагуванні. Натомість деталі, які не мають відношення одна до одної, як-от розмітка кнопки та розмітка бічної панелі, ізольовані одна від одної, що робить безпечну зміну кожної з них окремо.

Кожен компонент React — це функція JavaScript, яка може містити деяку розмітку, яку React відображає в браузері. Компоненти React використовують розширення синтаксису, яке називається JSX, для представлення цієї розмітки. JSX схожий на HTML, але трохи суворіший і може відображати динамічну інформацію. Найкращий спосіб зрозуміти це — перетворити деяку HTML-розмітку на розмітку JSX.

Note

JSX та React — дві різні речі. Їх часто використовують разом, але ви можете використовувати їх незалежно одне від одного. JSX є розширенням синтаксису, у той час, як React — бібліотека JavaScript.

Конвертація HTML в JSX

Припустимо, у вас є деякий (абсолютно правильний) HTML:

<h1>Список завдань Геді Ламари</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Геді Ламар (Hedy Lamarr)"
class="photo"
>
<ul>
<li>Винахід нових світлофорів
<li>Провести репетицію сцени з фільму
<li>Вдосконалення технології спектра
</ul>

І ви хочете вставити його у свій компонент:

export default function TodoList() {
return (
// ???
)
}

Якщо ви скопіюєте та вставите його як є, він не буде працювати:

export default function TodoList() {
  return (
    // Це не зовсім працює!
    <h1>Список завдань Геді Ламари</h1>
    <img 
      src="https://i.imgur.com/yXOvdOSs.jpg" 
      alt="Геді Ламар (Hedy Lamarr)" 
      class="photo"
    >
    <ul>
      <li>Винахід нових світлофорів
      <li>Провести репетицію сцени з фільму
      <li>Вдосконалення технології спектра
    </ul>

Це тому, що JSX строгіший і має декілька більше правил ніж HTML! Якщо ви прочитаєте повідомлення про помилки вище, вони нададуть вам вказівки щодо виправлення розмітки, або ви можете скористатися наступним посібником.

Note

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

Правила JSX

1. Повертайте один кореневий елемент

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

Наприклад, ви можете використовувати <div>:

<div>
<h1>Список завдань Геді Ламари</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Геді Ламар (Hedy Lamarr)"
class="photo"
>
<ul>
...
</ul>
</div>

Якщо ви не хочете додавати додатковий <div> до вашої розмітки, ви можете написати <> та </> замість нього:

<>
<h1>Список завдань Геді Ламари</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Геді Ламар (Hedy Lamarr)"
class="photo"
>
<ul>
...
</ul>
</>

Цей порожній тег називається Фрагмент. Фрагменти дозволяють вам групувати елементи без додавання додаткових тегів до HTML-структури сторінки.

Deep Dive

Чому декілька тегів JSX потрібно обгортати?

JSX виглядає схожим на HTML, але “під капотом” він перетворюється на звичайні об’єкти JavaScript. Ви не можете повернути два об’єкти з функції без обгортання їх у масив. Це пояснює, чому ви також не можете повернути два теги JSX без обгортання їх в інший тег або Фрагмент.

2. Закривайте всі теги

JSX вимагає явного закриття тегів: теги, які закриваються самі, такі як <img>, повинні бути записані як <img />, а теги, які обгортають щось, наприклад <li>oranges, мають бути написані як <li>oranges</li>.

Ось як виглядають закритими зображення та пункти списку Геді Ламари:

<>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Геді Ламар (Hedy Lamarr)"
class="photo"
/>
<ul>
<li>Винахід нових світлофорів</li>
<li>Провести репетицію сцени з фільму</li>
<li>Вдосконалення технології спектра</li>
</ul>
</>

3. camelCase для всіх більшості речей!

JSX перетворюється в JavaScript, а атрибути, записані в JSX, стають ключами об’єктів JavaScript. У ваших компонентах ви часто будете хотіти зчитувати ці атрибути у змінні. Але у JavaScript є обмеження на імена змінних. Наприклад, їх імена не можуть містити дефіси або бути зарезервованими словами, такими як class.

Ось чому в React багато атрибутів HTML та SVG записані у camelCase. Наприклад, замість stroke-width ви використовуєте strokeWidth. Оскільки class є зарезервованим словом, в React ви пишете className, названий за відповідною властивістю DOM:

<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Геді Ламар (Hedy Lamarr)"
className="photo"
/>

Ви можете знайти всі ці атрибути в списку властивостей DOM компоненту. Якщо ви допустите помилку, не хвилюйтесь - React надрукує повідомлення з можливим виправленням у консолі браузера.

Pitfall

З історичних причин атрибути aria-* та data-* записуються з дефісами, як у HTML.

Професійна порада: Використовуйте JSX конвертер

Конвертація всіх цих атрибутів у наявній розмітці може бути виснажливою! Ми рекомендуємо використовувати конвертер для перекладу вашого наявного HTML та SVG у JSX. Конвертери дуже корисні на практиці, але все ж варто розуміти, що відбувається, щоб ви могли зручно писати JSX самостійно.

Ось ваш кінцевий результат:

export default function TodoList() {
  return (
    <>
      <h1>Список завдань Геді Ламари</h1>
      <img 
        src="https://i.imgur.com/yXOvdOSs.jpg" 
        alt="Геді Ламар (Hedy Lamarr)" 
        className="photo" 
      />
      <ul>
        <li>Винахід нових світлофорів</li>
        <li>Провести репетицію сцени з фільму</li>
        <li>Вдосконалення технології спектра</li>
      </ul>
    </>
  );
}

Recap

Тепер ви розумієте, чому існує JSX і як його використовувати в компонентах:

  • Компоненти React групують логіку відображення разом з розміткою, оскільки вони пов’язані.
  • JSX схожий на HTML, з декількома відмінностями. Якщо потрібно, ви можете скористатися конвертером.
  • Повідомлення про помилки часто вкажуть вам правильний шлях для виправлення вашої розмітки.

Challenge 1 of 1:
Конвертація деякого HTML в JSX

Цей HTML був вставлений в компонент, але він не є валідним JSX. Виправте його:

export default function Bio() {
  return (
    <div class="intro">
      <h1>Ласкаво просимо на мій сайт!</h1>
    </div>
    <p class="summary">
      Ви можете знайти мої думки тут.
      <br><br>
      <b>Та <i>зображення</b></i> науковців!
    </p>
  );
}

Чи робити це вручну, чи скористатися конвертером - це ваш вибір!