JSX: расширение JavaScript и примеры использования

Автор: IT Sectr Опубликовано: 2026-07-03 Время чтения: 10 мин

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

Главное

  • JSX — синтаксический сахар над React.createElement, позволяющий писать HTML-подобную разметку в JavaScript.
  • Выражения в JSX встраиваются через фигурные скобки — можно использовать любые JS-выражения.
  • Атрибуты в JSX пишутся в camelCase (className, onClick, tabIndex), а не в kebab-case.
  • Транспиляция JSX в JS выполняется Babel, TypeScript или esbuild перед выполнением в браузере.
  • XSS-защита встроена — React экранирует все значения перед рендерингом, предотвращая инъекции.

Что такое JSX?

JSX (JavaScript XML) — синтаксическое расширение для JavaScript, впервые представленное в React в 2013 году. Оно позволяет разработчикам описывать структуру пользовательского интерфейса в декларативном стиле, комбинируя разметку и логику в одном файле.

До появления JSX разработчики использовали строковые шаблоны (Mustache, Handlebars) или создавали DOM-элементы вручную через document.createElement. Оба подхода имели недостатки: строковые шаблоны не проверялись на типы, а ручное создание DOM было громоздким и подверженным ошибкам.

React выбрал иной путь — встраивание разметки прямо в код. Это решение вызвало споры в сообществе, но со временем стало стандартом. Сегодня JSX используется не только в React, но и в SolidJS, Preact, Qwik и даже во Vue через плагины.

Базовый синтаксис JSX

JSX-элемент выглядит как HTML-тег, но встраивается непосредственно в JavaScript. Каждый элемент транслируется в вызов React.createElement с тремя аргументами: тип элемента, объект пропсов и дочерние элементы. Один корневой элемент — обязательное правило: JSX-выражение должно возвращать один родительский элемент или фрагмент.

js
import React from 'react';

// Basic JSX - single root element
const element = (
  <div className="app">
    <h1>Hello, World!</h1>
    <p>Welcome to React</p>
  </div>
);

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

Когда не нужен лишний DOM-узел, используйте React.Fragment или короткий синтаксис <></>. Фрагменты не создают реального DOM-элемента, а только группируют дочерние узлы. Это особенно полезно в таблицах и списках, где лишняя обёртка нарушила бы HTML-структуру.

js
function Columns() {
  return (
    <>
      <td>First</td>
      <td>Second</td>
    </>
  );
}

Выражения и переменные в JSX

Любое JavaScript-выражение встраивается в JSX через фигурные скобки { }. Внутри можно использовать переменные, вызовы функций, тернарные операторы и методы массивов. Условный рендеринг выполняется через тернарный оператор или логическое И.

js
function Greeting({ name, isLoggedIn }) {
  const items = ['Red', 'Green', 'Blue'];

  return (
    <div>
      {/* Expression with variable */}
      <h1>Hello, {name}</h1>

      {/* Conditional rendering */}
      {isLoggedIn ?
        <p>Welcome back!</p :
        <button>Login</button>
      }

      {/* Render array */}
      <ul>
        {items.map(item =>
          <li key={item}>{item}</li>
        )}
      </ul>
    </div>
  );
}

Ключевое ограничение — внутри фигурных скобок можно использовать только выражения, не инструкции. Нельзя использовать if/else, for, switch — только тернарный оператор, логические операторы и методы массивов. Вызов функций разрешён, включая стрелочные.

Отличия JSX от HTML

JSX визуально похож на HTML, но имеет принципиальные отличия. Атрибуты пишутся в camelCase — className вместо class, onClick вместо onclick, tabIndex вместо tabindex. Это связано с тем, что JSX транслируется в JavaScript, где дефис в имени свойства недопустим.

HTMLJSXПричина
class="wrapper"className="wrapper"class — зарезервированное слово в JS
onclick="handle()"onClick={handle}camelCase для JS-свойств
style="color: red"style={{ color: 'red' }}Объект стилей вместо строки
<input disabled><input disabled={true}>Явное указание булевых атрибутов

Ещё одно важное отличие — самозакрывающиеся теги. В HTML некоторые теги (br, hr, input) могут быть не закрыты. В JSX все самозакрывающиеся теги обязаны иметь закрывающий слеш: <br />, <input />. Имена SVG-атрибутов тоже конвертируются в camelCase: strokeWidth, fillOpacity.

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

Браузеры не понимают JSX напрямую. Перед выполнением JSX-код проходит через транспилятор — Babel, TypeScript или esbuild. Каждый JSX-элемент превращается в вызов createElement или jsx/runtime.

Трансформация через Babel

js
// Original JSX
const element = <h1 className="title">Hello</h1>;

// After transpilation
const element = React.createElement(
  'h1',
  { className: 'title' },
  'Hello'
);

С React 17 появилась новая JSX-трансформация, не требующая импорта React. Автоматический импорт jsx-runtime позволяет писать компоненты без import React from 'react'. Babel и TypeScript поддерживают эту трансформацию через настройку {"runtime": "automatic"}.

JSX вне React: Solid, Preact, Vue

Хотя JSX ассоциируется с React, другие фреймворки также его используют. SolidJS использует JSX с компиляцией в реальные DOM-ноды, без Virtual DOM. Preact — лёгкая альтернатива React с полной поддержкой JSX. Vue поддерживает JSX через @vue/babel-plugin-jsx, хотя его основной шаблон — template.

Ключевое различие — семантика выражений. В React JSX-выражения выполняются при каждом рендере. В SolidJS JSX компилируется один раз, и обновления отслеживаются через сигналы. Это влияет на производительность: SolidJS не требует Virtual DOM и reconsilation, поэтому JSX-рендеринг быстрее.

В TypeScript JSX поддерживается на уровне языка. Файлы с расширением .tsx автоматически обрабатывают JSX-синтаксис. Типизация пропсов — одно из главных преимуществ TypeScript + JSX: IDE подсказывает ожидаемые атрибуты, типы колбэков и обязательность пропсов.

Лучшие практики работы с JSX

Пишите JSX-код, который легко читать и поддерживать. Выносите сложные выражения в отдельные переменные или функции — это улучшает читаемость и позволяет тестировать логику отдельно от разметки. Используйте фрагменты вместо лишних div-обёрток.

Правило табуляции — соблюдайте отступы для вложенных элементов. Каждый уровень вложенности — один уровень отступа. Закрывающий тег должен быть на уровне открывающего. Для длинных атрибутов используйте перенос строки.

Избегайте inline-стрелочных функций в пропсах, если они создаются на каждый рендер. В таких случаях оборачивайте колбэк в useCallback или выносите функцию за пределы компонента. Разделяйте сложные компоненты на более мелкие — каждый компонент должен отвечать за одну логическую единицу интерфейса.

Часто задаваемые вопросы

Можно ли использовать JSX без React?

Да, через Babel-плагин @babel/plugin-transform-react-jsx можно настроить JSX для любой библиотеки. SolidJS, Preact, Nerv и другие фреймворки используют JSX с собственными runtime. Для полной независимости можно указать pragma на свою функцию.

Почему в JSX нельзя использовать class вместо className?

class — зарезервированное слово в JavaScript. JSX транслируется в createElement, где вторым аргументом передаётся объект пропсов. Свойство class конфликтует с классовым синтаксисом ES6, поэтому React выбрал className.

Как добавить несколько классов в JSX?

Используйте шаблонные строки или библиотеку classnames: className={`"btn ${isActive ? 'active' : ''}"`}. Для сложной логики подключите npm-пакет clsx или classnames, которые принимают объекты и массивы.

Поддерживает ли JSX условные конструкции?

JSX поддерживает только выражения, не инструкции. Для условий используйте тернарный оператор, логическое И (&&) или логическое ИЛИ (||). Для сложной логики выносите условие в отдельную переменную или функцию.

Почему в JSX нужен key для списков?

Атрибут key помогает React идентифицировать элементы списка при ререндере. Без key React перерисовывает весь список при изменении. С уникальным key React переиспользует DOM-ноды и переупорядочивает элементы, а не пересоздаёт их.

Итоги

  • JSX — XML-подобное расширение JavaScript для декларативного описания UI, альтернатива строковым шаблонам.
  • Фигурные скобки позволяют встраивать любые JS-выражения — переменные, функции, тернарные операторы.
  • Атрибуты в JSX пишутся в camelCase, стили передаются объектом, булевы атрибуты — явно.
  • Транспиляция JSX в createElement выполняется Babel или TypeScript автоматически.
  • Один корневой элемент или фрагмент обязателен для каждого JSX-выражения.
  • JSX вне React — SolidJS, Preact, Vue и Qwik также поддерживают JSX через собственные runtime.
  • TypeScript с .tsx расширением даёт полноценную типизацию пропсов и атрибутов JSX.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также