7 - Что такое JSX? Отличие от HTML

Оценить качество материала и подачу материала автором видео:

Front-end

Трудоустройтесь middle front-end разработчиком на React JS (TypeScript) за 12-16 месяцев обучения с ежедневной менторской поддержкой в формате видео 1 на 1 и коммерческими проектами в портфолио

Перейти на курс
Front-end

Back-end

Трудоустройтесь middle back-end разработчиком за 12-16 месяцев обучения с ежедневной менторской поддержкой в формате видео 1 на 1 и коммерческими проектами в портфолио

Перейти на курс
Back-end

Карьерный бустер

Получите коммерческий опыт на реальных стартапах, прокачайте tech & soft навыки, научитесь работать в команде, проходить собеседования и получите первую работу в IT!

Перейти на курс
Карьерный бустер

Основы Front-end

Сделайте первый шаг в IT, освоив базовые знания разработки и научившись создавать небольшие проекты на JavaScript

Перейти на курс
Основы Front-end

Основы Back-end

Сделайте первый шаг в IT, освоив базовые знания разработки. Без опыта. Без математики. Только практика: JavaScript, SQL, Node JS, база данных

Перейти на курс
Основы Back-end

Различия между HTML и JSX

Автор конспекта: Арина Василевская

Для данного урока рекомендуется создать новый React-проект с помощью Vite.

Создадим два файла test.html:

test.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
  </head>
  <body>
    <script></script>
  </body>
</html>

и App.tsx:

App.tsx
import "./App.css"
function App() {
  return <></>
}
 
export default App

JSX ≠ HTML

Главное отличие в том, что JSX — это не HTML, а JavaScript-синтаксис. Он описывает инструкции, по которым React создаёт DOM-элементы и управляет ими. React выступает как посредник: берёт на себя рутинную работу с реальными элементами, делая процесс эффективнее и позволяя разработчику сосредоточиться на бизнес-логике приложения.

Виды HTML-тегов

1. Обычные (парные) теги

Имеют открывающий тег <tag> и закрывающий тег </tag>. Между ними находится содержимое. Используются тогда, когда у элемента есть контент. Например, тег <div>.

2. Void-теги (самозакрывающиеся, одиночные)

Эти теги создают на странице самостоятельный элемент и не предназначены для того, чтобы содержать внутри себя текст или другие теги. Поэтому их называют одиночными: они не имеют содержимого и не требуют закрывающего тега. Например, тег <hr/>.

📌

Ранее одиночные теги было принято завершать с помощью дополнительного слэша (/) перед закрывающей скобкой, например: <input/> . В стандарте HTML5 такое написание считается необязательным, поэтому одиночные теги можно оформлять как со слэшем, так и без него.

🔗 Более подробно о тегах можно почитать, перейдя по ссылкам:

Все void-элементы в JSX должны быть самозакрывающимися. Причина: JSX — это JavaScript-синтаксис, а не HTML. У компилятора должно быть чёткое понимание: есть ли у тега содержимое или нет.

Добавим тег <div>, с вложенным в него тегом <input/> со значением "it-incubator.io".

test.html
<!--...-->
<body>
  <div>
    <input value="it-incubator.io" />
  </div>
  <script></script>
</body>
 
<!--...-->

В App.tsx заменим наш фрагмент на аналогичный <div> из test.html:

App.tsx
// ...
 
return (
  <div>
    <input value="it-incubator.io" />
  </div>
)
 
// ...

Контролируемые и неконтролируемые элементы

При открытии проектов в браузере мы видим, что в test.html значение input можно менять, а в App.tsx нет. Почему же так происходит?

  • HTML: поля ввода (например, <input>) по умолчанию работают самостоятельно — пользователь может свободно менять их содержимое. Такие элементы называют неуправляемыми.

  • JSX: если для input задать свойство value, его состояние начинает контролироваться React. Если вы попытаетесь изменить значение вручную, React быстро вернёт его к заданному value, поддерживая его актуальность. React активно отслеживает события на странице: он перехватывает события на корневом div и обрабатывает их, выступая прослойкой между JSX и реальными DOM-элементами, чтобы корректно реагировать на взаимодействия пользователя.

События, которые происходят с элементами можно посмотреть в консоли разработчика:

EventListener

Атрибуты vs Пропсы

Атрибуты

В HTML то, что мы передаём внутрь элемента, называется атрибутами. По сути, мы настраиваем элемент, передавая ему значения, которые определяют его поведение. Например, можно задать входное значение value или ограничить максимальную длину maxlength.

test.html
<!--...-->
<input value="search" maxlength="15" id="title" />
<!--...-->

Особенности атрибутов в HTML:

  • Значение атрибута всегда интерпретируется как строка. Даже если мы пишем число, браузер воспринимает его как текст.
  • HTML допускает опускание кавычек для простых значений, но обычно их ставят.
  • Булевыe атрибуты: наличие такого атрибута (например, disabled) делает элемент неактивным, независимо от того, какое значение ему присвоено (disabled, disabled="true", disabled="false", disabled="" — все приведут к одному результату). Главное — само присутствие атрибута.

Пропсы

App.tsx
// ...
 
return (
  <div>
    <input value="it-incubator.io" maxLength={15} id={"title"} />
  </div>
)
 
// ...

В React (JSX) вместо атрибутов используются props. Пропсы(props) — это свойства JavaScript-объекта, которые передаются компоненту или элементу. Они могут содержать значения любого типа: строки, числа, булевы значения, массивы, объекты и т.д.

🔗

Ссылка на документацию React Components

Особенности пропсов в JSX:

  • Чувствительность к регистру: имена пропсов соответствуют свойствам объектов JavaScript. Для названий props используется camelCase Например, maxlength в HTML становится maxLength в JSX/TypeScript. При работе TypeScript подсказывает верное написание.
  • Типизация: TypeScript помогает строго типизировать пропсы. Например, для maxLength ожидается число, а не строка, поэтому передаем его в фигурных скобках: 15.
  • Булевыe значения: в JSX boolean props задаются явно:
  • disabled={true} — элемент неактивен.
  • disabled={false} — элемент активен (атрибут disabled не добавляется в DOM).

Стили

Inline styles

В HTML inline styles(инлайновые стили) представляют собой одну большую строку, что неудобно для работы. Это не лучшая практика, но иногда применяется, например, при быстром изменении внешнего вида элемента в ответ на действия пользователя.

Особенности:

  • свойства отделяются друг от друга точкой с запятой;
  • названия свойств пишутся так же, как в CSS — в формате kebab-case;
test.html
<!--...-->
<input
  id="title"
  value="search"
  maxlength="15"
  style="color: red; border: 1px solid green; background-color: yellow"
/>
<!--...-->

В JSX inline styles называются CSS-in-JS и передаются как объект JavaScript, где ключ — это имя свойства CSS, а значение — его значение.

App.tsx
// ...
<input
  id={"title"}
  value="it-incubator.io"
  maxLength={15}
  style={{
    color: "red",
    border: "1px solid green",
    backgroundColor: "yellow",
  }}
/>
// ...

Особенности:

  • поскольку JSX позволяет использовать выражения JavaScript внутри фигурных скобок, для передачи объекта стилей используются двойные фигурные скобки {{}}.
  • свойства отделяются запятыми, а не точкой с запятой.
  • для названий свойств CSS используется camelCase(например, backgroundColor вместо background-color).

CSS-классы

Инлайновые стили быстро «захламляют» код и отвлекают от логики. Поэтому чаще стили выносят в отдельные CSS-файлы и подключают через классы. В файле index.css создадим класс title:

index.css
.title {
  color: red;
  border: 3px solid green;
  background-color: yellow;
}

В HTML класс задаётся атрибутом class.

test.html
<!--...-->
<input id="title" value="search" maxlength="15" class="title" />
<!--...-->

В JSX используется не class, а className:

App.tsx
// ...
<input id={"title"} value="it-incubator.io" maxLength={15} className="title" />
// ...
📌

В JavaScript ключевое слово class зарезервировано для объявления классов. Так как в React элементы представляют собой объекты DOM, у них используется свойство className, а не class. Поэтому React следует DOM-модели и устанавливает классы через DOM API: element.className.

При инспекции в браузере (F12) атрибут class всё равно виден в разметке, но на уровне объекта DOM React работает именно со свойством className.

Можно также присваивать несколько классов, это делается через пробел, как в HTML, так и в JSX:

test.html
<!--...-->
<input id="title" value="search" maxlength="15" class="title input" />
<!--...-->
App.tsx
// ...
<input id={"title"} value="it-incubator.io" maxLength={15} className="title input" />
// ...
🔗

Подробнее о Style и class


🏠 Домашнее задание

Различия между HTML и JSX

Цель задания

Закрепить понимание различий между HTML-атрибутами и JSX-пропсами, научиться корректно переводить HTML-разметку в JSX.

Задание 1

Подготовка

  1. Создайте новый React-проект с помощью Vite. Можете делать домашнее задание в проекте в котором вы учились создавать проект (lesson-04)
  2. Удалите файл index.css
  3. Удалите все стили из App.css. Файл не удаляйте, в дальнейшем он пригодится
  4. В App.tsx удалите весь шаблонный код и отрисуйте разметку, приведенную ниже
App.tsx
export function App() {
  return (
    <>
      <h1>Мой музыкальный плеер</h1>
    </>
  )
}

Поправьте импорт в main.tsx

  1. Запустите проект и убедитесь, что в браузере вы увидели заголовок Мой музыкальный плеер

Задание 2

Преобразование HTML в JSX

  1. Создайте в src директории новый файл player.html и вставьте в него следующий HTML-код
player.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Мой музыкальный плеер</title>
  </head>
  <body>
    <div class="music-player">
      <h4>1. Классы</h4>
      <h1 id="title" style="color: blue; background-color: yellow; border: 2px solid red;">
        Мой музыкальный плеер
      </h1>
      <hr />
 
      <h4>2. maxlength</h4>
      <input
        type="search"
        id="search"
        placeholder="Поиск музыки"
        maxlength="50"
        value="Начните печатать..."
      />
      <hr />
 
      <h4>3. rows, cols, maxLength, readonly</h4>
      <textarea
        placeholder="Оставьте комментарий к треку..."
        rows="3"
        cols="40"
        maxlength="200"
        readonly
      ></textarea>
      <hr />
 
      <h4>4. tabindex</h4>
      <button tabindex="0">Click</button>
      <hr />
 
      <h4>5. colspan, rowspan</h4>
      <table border="1">
        <tbody>
          <tr>
            <td colspan="2">1</td>
            <td rowspan="3">2</td>
          </tr>
        </tbody>
      </table>
      <hr />
 
      <h4>6. for</h4>
      <input type="radio" id="repeat-off" name="repeat" />
      <label for="repeat-off">Без повтора</label>
      <hr />
    </div>
  </body>
</html>
  1. Откройте player.html в браузере и убедитесь что на экране будет отображение html разметки
  2. В файле App.tsx перепишите html разметку в JSX, исправив все ошибки и адаптировав под React

В итоге вы должны получить точно такой же результат как и в player.html

les7-res-2

Задание 3

Работа со стилями

  1. В файле App.css создайте новый класс .player-title, перенесите инлайновые заголовка Мой музыкальный плеер и примените полученный класс в App.tsx
  2. Добавьте стили для всего блока (music-player) и добавьте в App.tsx.
  3. Для input и textarea добавьте новый класс form-control. А также сделайте неактивными input и textarea повесив на них нужный атрибут
css
.player-title {
  /* ваши стили */
}
 
.music-player {
  padding: 20px;
  max-width: 600px;
  margin: 0 auto;
}
 
.form-control {
  width: 600px;
  padding: 20px;
  box-sizing: border-box;
}

Должен получиться следующий результат 🚀

les7-res-3


💡

Совет: Если что-то кажется сложным, не переживайте! Это нормально на начальном этапе. Главное — это практика и постепенное понимание концепций React.

Боевой маршрут (React Путь Самурая: без альтернатив)

Видеоурок - 8 видео из 30