Олег Марков
Как работает 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
Один корневой элемент
Каждый JSX-фрагмент должен иметь только один корневой элемент. Например, так нельзя:// Так делать нельзя! return ( <h1>Заголовок</h1> <p>Абзац</p> );
А вот так — правильно:
return ( <div> <h1>Заголовок</h1> <p>Абзац</p> </div> );
Или можно использовать <React.Fragment> (или сокращенно
<> ... </>
) для группировки:return ( <> <h1>Заголовок</h1> <p>Абзац</p> </> );
CamelCase для свойств — отличие от HTML
Имена атрибутов в JSX обычно пишутся в camelCase-стиле:class
превращается вclassName
for
превращается вhtmlFor
- style оформляется как объект
Пример:
<div className="box" htmlFor="inputId" style={{color: 'red', backgroundColor: 'yellow'}}> Привет! </div>
// Здесь className — это аналог class из HTML, style принимает объект, а не строку.
Встраивание выражений JavaScript
Самое мощное в JSX — это возможность встраивать внутрь разметки выражения на JavaScript, просто заключая их в фигурные скобки{}
:const name = 'Сергей'; return <h1>Привет, {name}!</h1>; // Здесь {name} будет заменено значением переменной
Можно использовать любые валидные выражения JavaScript (но не инструкции, например, if нельзя — для этого используют тернарный оператор или возвызы функций).
Комментарии внутри 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-стилем.
Постройте личный план изучения React до уровня Middle — бесплатно!
React — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по React
Лучшие курсы по теме

React и Redux Toolkit
Антон Ларичев
TypeScript с нуля
Антон Ларичев