логотип PurpleSchool
логотип PurpleSchool

Как работает JSX связка React и HTML

Автор

Олег Марков

Введение

JSX — это расширение синтаксиса для JavaScript, используемое в React. На первый взгляд он очень напоминает HTML, но на самом деле это не просто шаблонный язык, а инструмент, который помогает описывать интерфейсы React-компонентов прямо в JavaScript-коде. Зачем это нужно? Используя JSX, вы можете создавать гибкие, динамические пользовательские интерфейсы, при этом ваш код становится более читабельным и наглядным. Давайте вместе разберемся, как именно работает JSX, как он "связывает" React и HTML, и зачем вообще понадобился этот синтаксис.

Что такое JSX и почему он похож на HTML

JSX отличается от привычного HTML, несмотря на внешнее сходство. Когда вы пишете код с разметкой, похожей на HTML, на самом деле вы используете особый синтаксис, который в конечном итоге преобразуется в вызовы JavaScript-функций (чаще всего React.createElement). То есть, когда вы пишете такой код:

const element = <h1>Привет, мир!</h1>;

его реальное "исполнение" выглядит вот так (после компиляции):

const element = React.createElement('h1', null, 'Привет, мир!');

Здесь вы видите, что на этапе компиляции JSX превращается в обычный JavaScript-код. Именно этот момент и делает JSX мощным инструментом для React-разработки — он позволяет писать декларативный код, который потом транслируется в вызываемые функции.

JSX — это мощный инструмент, который позволяет писать HTML-подобный код непосредственно в JavaScript. Он упрощает создание иерархической структуры компонентов и делает код более читаемым и поддерживаемым. Глубокое понимание принципов работы JSX — это важный навык для любого React-разработчика. Если вы хотите детальнее погрузиться в тонкости JSX и узнать, как он преобразуется в обычный JavaScript — приходите на наш большой курс Основы React, React Router и Redux Toolkit. На курсе 177 уроков и 17 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Краткая история появления JSX

JSX появился как попытка объединить декларативность шаблонов (как в HTML) с гибкостью JavaScript. Использование его заметно ускоряет создание сложных пользовательских интерфейсов: то, что раньше требовало создания шаблонов и ручного связывания их с логикой, теперь можно разместить в одном файле, сохраняя логику и представление рядом.

Синтаксис JSX

Чтобы вы могли быстро начать писать на JSX, разберем основные правила и особенности его синтаксиса.

Основные правила написания JSX

  1. Один корневой элемент
    Каждый JSX-фрагмент должен иметь только один корневой элемент. Например, так нельзя:

    // Так делать нельзя!
    return (
      <h1>Заголовок</h1>
      <p>Абзац</p>
    );

    А вот так — правильно:

    return (
      <div>
        <h1>Заголовок</h1>
        <p>Абзац</p>
      </div>
    );

    Или можно использовать <React.Fragment> (или сокращенно <> ... </>) для группировки:

    return (
      <>
        <h1>Заголовок</h1>
        <p>Абзац</p>
      </>
    );
  2. CamelCase для свойств — отличие от HTML
    Имена атрибутов в JSX обычно пишутся в camelCase-стиле:

    • class превращается в className
    • for превращается в htmlFor
    • style оформляется как объект

    Пример:

    <div className="box" htmlFor="inputId" style={{color: 'red', backgroundColor: 'yellow'}}>
      Привет!
    </div>

    // Здесь className — это аналог class из HTML, style принимает объект, а не строку.

  3. Встраивание выражений JavaScript
    Самое мощное в JSX — это возможность встраивать внутрь разметки выражения на JavaScript, просто заключая их в фигурные скобки {}:

    const name = 'Сергей';
    return <h1>Привет, {name}!</h1>;
    // Здесь {name} будет заменено значением переменной

    Можно использовать любые валидные выражения JavaScript (но не инструкции, например, if нельзя — для этого используют тернарный оператор или возвызы функций).

  4. Комментарии внутри JSX
    Комментарии пишутся как {/* ... */}:

    return (
      <div>
        {/* Это комментарий внутри JSX */}
      </div>
    );

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

  • В JSX нельзя использовать зарезервированные слова JavaScript (например, нельзя <label for="id">, только <label htmlFor="id">);
  • Атрибуты пишутся в camelCase;
  • Все теги должны быть закрыты (например, <img src="..." />, <input />);
  • Для передачи JavaScript-логики используют фигурные скобки;
  • JSX можно сохранить в переменную, можно возвращать из функций, можно передавать в другие компоненты.

Как JSX превращается в JavaScript: пошаговый разбор

Давайте на практике посмотрим, что происходит "за кулисами", когда вы пишете JSX.

Пример преобразования JSX в createElement

Исходный JSX:

const el = (
  <button className="btn" onClick={() => alert('Нажато!')}>
    Нажми меня!
  </button>
);

Этот код преобразуется в следующее (на этапе компиляции):

const el = React.createElement(
  'button',
  {
    className: 'btn',
    onClick: () => alert('Нажато!'),
  },
  'Нажми меня!'
);

Такой подход позволяет React эффективно управлять деревом элементов (Virtual DOM), обновлять только те части интерфейса, которые изменились, и обеспечивать высокую производительность.

Как работает Virtual DOM с JSX

Когда вы специфицируете дерево компонентов через JSX, React создает описание этого дерева в оперативной памяти — это и есть Virtual DOM. При изменении состояния компонента React сравнивает старое и новое описание дерева (процесс называется reconciliation, или согласование) и вносит только минимальные необходимые изменения в настоящий DOM браузера.

JSX и работа с динамическими данными

С помощью JSX можно динамически строить интерфейс, комбинируя JavaScript-выражения и структуры данных прямо внутри разметки.

Вставка переменных

const username = 'Вика';
return <h2>Привет, {username}!</h2>;
// {username} подставит 'Вика' прямо в заголовок

Шаблоны со списками

Часто нужно выводить списки данных. Вот простой пример:

const users = ['Анна', 'Игорь', 'Сергей'];

// Используем map для вывода списка
return (
  <ul>
    {users.map(user => (
      <li key={user}>{user}</li>
    ))}
  </ul>
);
// key необходим для отслеживания изменений в списке

Условия и логика

В JSX нельзя писать конструкции типа if/else — используйте выражения:

const isLoggedIn = true;

return (
  <div>
    {isLoggedIn ? <p>Добро пожаловать!</p> : <p>Пожалуйста, зарегистрируйтесь.</p>}
  </div>
);
// Здесь отображается разный текст в зависимости от значения isLoggedIn

Если нужно условно не рендерить компонент — можно возвращать null или использовать логическое "И":

const showDetails = false;
return (
  <div>
    Основной текст
    {showDetails && <span>Подробнее...</span>}
  </div>
);
// В этом примере span отрисуется, только если showDetails === true

Как обратиться из JSX к функциям

Вы можете вставлять любые выражения, например, вызвать функцию:

function getGreeting(name) {
  return `Привет, ${name}`;
}

return <h3>{getGreeting('Екатерина')}</h3>;
// Здесь в JSX отрисуется "Привет, Екатерина"

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

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

const styleObj = {
  color: 'blue',
  fontWeight: 'bold',
};

return <div style={styleObj}>Текст с синим цветом</div>;

Обратите внимание, имена CSS-свойств пишутся в camelCase (backgroundColor, fontWeight). Также, если требуется задать несколько классов, их объединяют строкой:

return <div className="box primary">Блочный элемент</div>;

Фрагменты и группировка элементов

Если не хочется добавлять лишние контейнеры типа <div>, можно воспользоваться фрагментами:

return (
  <>
    <h2>Заголовок</h2>
    <p>Описание</p>
  </>
);
// При рендере этих элементов в DOM не появится лишней обертки.

JSX, компоненты и свойства (props)

JSX неразрывно связан с понятием компонента в React. Давайте разберем, как это использовать.

Передача props

function Welcome(props) {
  return <h1>Привет, {props.name}!</h1>;
}

// Использование:
return <Welcome name="Иван" />;
// Здесь props.name будет равен 'Иван'

Можно сразу использовать деструктуризацию:

function Welcome({name}) {
  return <h1>Привет, {name}!</h1>;
}

Композиция компонентов через JSX

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

function App() {
  return (
    <div>
      <Welcome name="Иван" />
      <Welcome name="Анна" />
      <Welcome name="Ольга" />
    </div>
  );
}

JSX и выражения JavaScript

Важно помнить: в JSX недопустимы инструкции JavaScript (например, if, for, while), но можно использовать всё, что возвращает значение: выражения, вызовы функций и т.п.

Пример с вызовом функции и переменных

const age = 30;

function getStatus(age) {
  if (age >= 18) return 'Совершеннолетний';
  return 'Несовершеннолетний';
}

return <span>{getStatus(age)}</span>;

Особенности обработки событий и inline-обработчики

В JSX вы привязываете обработчики событий с помощью camelCase и передаете функции:

function handleClick() {
  alert('Нажали на кнопку!');
}

return <button onClick={handleClick}>Нажать</button>;

Или используете inline-функцию:

return <button onClick={() => alert('Быстро нажали!')}>Еще раз</button>;

JSX и Children: передача вложенного контента

Один из мощных паттернов — использовать свойство children для передачи вложенного контента:

function Panel({ children }) {
  return <div className="panel">{children}</div>;
}

return (
  <Panel>
    <p>Это содержимое панели</p>
  </Panel>
);

Использование JSX вне React

JSX создан специально для React, но существует и поддержка для других библиотек (например, Preact, Inferno). При этом принцип компиляции остается тот же: JSX преобразуется в вызовы функций, которые формируют виртуальное DOM-дерево.

Инструменты для работы с JSX: компиляция и транспиляция

Браузеры не понимают JSX напрямую — его необходимо преобразовать в JavaScript. Обычно для этого используется Babel — транспилятор, встроенный во многие сборщики (Webpack, Vite и другие).

В package.json проекта с React вы найдете настройку для Babel, которая позволяет использовать JSX без дополнительной настройки. Современные Create React App, Next.js или Vite уже все это включают "из коробки".

Валидация и ограничения JSX

  • Все открывающиеся теги должны быть закрыты (<br />, <img ... />, <input ... />).
  • Атрибуты пишутся в camelCase.
  • Передача объектов внутрь атрибутов (например, пропсы со стилями, обработчики).
  • Все разметки должны быть внутри единственного корневого элемента (обертки).

Ошибки и типичные проблемы при работе с JSX

Вот некоторые из них и подсказки по их устранению:

  • Ошибка "Adjacent JSX elements must be wrapped in an enclosing tag"
    Возникает, если в return вы вернули сразу два или более JSX-элементов без обертки. Всегда оборачивайте их лишним контейнером или фрагментом.
  • Ошибка атрибута (например, class вместо className)
    JSX не поймет, если вы напишете <div class="foo"> — пишите <div className="foo">.
  • Попытка вставить инструкцию JavaScript внутрь JSX
    Внутри {} только выражения, не инструкции. If/else заменяйте на тернарный оператор.

Заключение

JSX — это не просто улучшенный HTML, а инструмент, который дает вам огромную свободу при проектировании UI в React-приложениях. Благодаря JSX вы описываете внешний вид компонентов декларативно, сочетая логику и разметку в одном месте. Весь код, написанный в JSX, в конечном итоге становится JavaScript-функциями, что делает ваши интерфейсы гибкими, динамическими и легко тестируемыми. Помните о синтаксических особенностях, отличиях от HTML, правилах написания атрибутов и организация кода с помощью фрагментов и props — и ваши React-компоненты будут работать быстро и без ошибок.

JSX это лишь часть экосистемы React. Чтобы создавать сложные и интерактивные приложения, необходимо освоить другие инструменты, такие как React Router и Redux Toolkit. На курсе Основы React, React Router и Redux Toolkit вы научитесь использовать их в связке. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в основы React уже сегодня.

Частозадаваемые технические вопросы по теме статьи и ответы на них

Вопрос 1: Как использовать условный рендеринг, если логика слишком сложная для тернарного оператора?
Ответ: Создайте функцию, которая возвращает нужный JSX-фрагмент, или вынесите всю логику выше по коду, сохранив результат в переменную, и используйте в JSX только {myContent}, например: jsx let content; if (user.isLoading) { content = <Loader />; } else if (user.error) { content = <ErrorMessage />; } else { content = <Profile user={user} />; } return <div>{content}</div>;

Вопрос 2: Почему не работает обработчик событий, если он объявлен как onClick="doSomething()"?
Ответ: В JSX обработчики событий нужно передавать как функцию, без кавычек, вот так: <button onClick={doSomething}>Кнопка</button>. Если вы напишете с кавычками, передается строка, а не ссылка на функцию.

Вопрос 3: Как добавить атрибут data- к элементу в JSX?
*
Ответ: Используйте обычный синтаксис camelCase или дефис — оба варианта поддерживаются:
<div data-user-id="42">User</div>

Вопрос 4: Как в React через JSX встроить HTML-разметку из строки?
Ответ: Для внедрения "сырых" HTML используется dangerouslySetInnerHTML: jsx <div dangerouslySetInnerHTML={{ __html: someHtmlString }} /> Используйте только с доверенными данными — иначе возможно внедрение XSS.

Вопрос 5: Как работать с событиями клавиатуры или мыши в JSX?
Ответ: Обработчики событий передаются как onKeyDown, onKeyUp, onMouseMove, и получают объект события: jsx <input onKeyDown={e => console.log(e.key)} /> <div onMouseMove={e => handleMouseMove(e)} /> Вы можете использовать все стандартные события React с приставкой on и camelCase-стилем.

Стрелочка влевоЧто такое props в React и как их правильно использоватьЧто такое React.js и как его использоватьСтрелочка вправо

Постройте личный план изучения React до уровня Middle — бесплатно!

React — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по React

Открыть базу знаний

Лучшие курсы по теме

изображение курса

React и Redux Toolkit

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий