Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Компоненты JS: React

Взгляните на пример, который будет разбираться в течение урока:

Центральное понятие в React – компонент. Более того, это единственная сущность, которую он содержит. Вся остальная функциональность построена вокруг компонентов.

В примере выше создан компонент, который добавляет <div>Hello!</div> в DOM страницы.

Вот как выглядит получившийся html:

<div id="react-root">
  <div>Hello!</div>
</div>

Импорты

CodePen импортирует React автоматически (его нужно указать в подключаемых библиотеках), но в своём коде импорты пропускать нельзя:

import React from 'react';
import ReactDOM from 'react-dom/client';

Из кода и импортов видно, что для работы с React нужно две библиотеки: сам React и ReactDOM. Причина наличия двух зависимостей достаточно проста. Сама библиотека React не связана с DOM напрямую и используется не только в браузере. Поэтому отрисовка конкретно для DOM вынесена в отдельный пакет ReactDOM.

Компонент

export default class Hello extends React.Component {
  render() {
    return <div>Hello</div>;
  }
}

Очевидные тезисы

  1. Компонент React – это класс, который наследуется от класса React.Component (как вы увидите позже, это не единственный способ создать компонент).
  2. Функция render возвращает нечто (рассмотрим позже), что будет отрисовано в браузере. Класс-компонент без функции render существовать не может, это его интерфейс.

Экспорт класса по умолчанию задан неспроста. В JS принято создавать один класс на файл. В отличие от обычных классов, React-компоненты имеют расширение JSX, а значит компонент, определённый выше, должен лежать в файле с именем Hello.jsx.

Обратите внимание: класс всё равно проименован, хотя это и не обязательно в случае дефолтного экспорта. Вы действительно можете его не именовать, но тогда через расширение React Dev Tools будет тяжело понять, что же отрисовал React, так как любой безымянный компонент отображается как <ReactComponent>. Поэтому возьмите себе за правило всегда давать компонентам имена.

Неочевидные тезисы

Самое поразительное происходит в этой строчке:

return <div>Hello</div>;

Здравый смысл подсказывает, что такая запись синтаксически невозможна в JS. И он будет прав. То, что вы видите, называется JSX и является расширением языка (добавляется с помощью Babel). Кардинальное решение для фреймворка, не правда ли? В процессе вы поймёте, что это не такая уж и плохая идея.

Главное сейчас запомнить то, что в конечном итоге любой React-компонент возвращает кусок DOM (на самом деле – виртуальный DOM).

Кстати, div – это тоже компонент React, только встроенный. Отличить встроенные компоненты от самописных очень легко. Встроенные всегда начинаются с маленькой буквы, а те, которые не являются частью React, должны начинаться с большой.

Хорошим стилем считается давать расширение .jsx для всех файлов, которые содержат JSX, независимо от того, создаётся ли компонент в этом файле или нет.

Mount

const root = ReactDOM.createRoot(document.getElementById('react-root'));
root.render(<Hello />);

Созданный компонент (класс компонента) сам по себе ничего не делает. Чтобы насладиться результатом его работы нужно произвести так называемое монтирование. То есть указать React, куда его вставить в DOM.

Для этой задачи обязательно требуется реальный DOM-узел. Подходящим может быть любой узел внутри body. Как правило, если у вас не SPA, то React используется в виде виджетов, подключаемых на странице в разных местах. Причём на одной странице может быть сразу несколько виджетов. Например, на Хекслете все фронтенд-элементы – это как раз виджеты. На основе узла создаётся контейнер приложения строчкой:

const root = ReactDOM.createRoot(document.getElementById('react-root'));

Далее в контейнер производится монтирование компонента:

root.render(<Hello />);

В качестве параметра передаётся компонент в синтаксисе JSX.

JSX

JSX – это похожее на XML-разметку расширение для JavaScript, созданное специально для задач React. React из коробки поставляется с набором компонентов, которые полностью повторяют HTML. По большей части синтаксис и структура JSX и HTML совпадают, но есть некоторые важные различия:

  1. Так как это похожий на XML синтаксис, одиночные теги в JSX должны быть закрыты: <hr />.
  2. Вместо атрибута class в JSX используется имя свойства в DOM: className.

Существуют и другие различия, о которых будет рассказываться в следующих уроках. Большинство этих отличий делает работу с DOM внутри React проще и удобнее.

Так же как и в HTML, из компонентов можно строить композиции, например такую:

const vdom = (
  <div className="card">
    <div className="card-body">
      <h4 className="card-title">Card title</h4>
      <p className="card-text">my text</p>
      <a href="#" className="btn btn-primary">
        Go somewhere
      </a>
    </div>
  </div>
);

И это всё валидный код на JS с подключённым расширением для JSX.

То, что каждый компонент React возвращает кусок DOM, является следствием его фундаментальной идеи и архитектуры. В одном из уроков эта идея будет рассмотрена подробнее, и вы наверняка проникнитесь ей. Но почему понадобилось вводить JSX?

Нужно понимать, что JSX – расширение языка, а значит это именно код, а не html. А раз JSX транслируется в код, то, следовательно, вы могли бы сразу писать этот код. Верно? Верно, но не совсем:

React.createElement(
  "div",
  { className: "card" },
  React.createElement(
    "div",
    { className: "card-body" },
    React.createElement(
      "h4",
      { className: "card-title" },
      "Card title"
    ),
    React.createElement(
      "p",
      { className: "card-text" },
      "my text"
    ),
    React.createElement(
      "a",
      { href: "#", className: "btn btn-primary" },
      "Go somewhere"
    )
  )
);

Пример кода выше – это как раз то, как бы выглядели функции render компонентов на React. Причём данный пример очень тривиальный и не содержит логику. Если бы у вас появились условные конструкции, то этот код перешёл бы все разумные пределы по сложности анализа. К сожалению, или к счастью, собирать древовидные структуры в коде (а DOM – это дерево) – занятие очень тяжёлое и беспощадное. Теперь должно стать чуть понятнее, зачем нужен JSX, и что JSX – это не вёрстка (как думают некоторые).

Ну и последнее. Так как любой JSX в итоге превращается транспилятором в вызовы React.createElement, то нужно следить за тем, чтобы React был импортирован: import React from 'react'.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов для веб-приложений
6 октября 10 месяцев
Иконка программы Fullstack-разработчик
Профессия
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
6 октября 16 месяцев

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и соглашаетесь с «Условиями использования»