Как работает JSX?

JSX (JavaScript XML) — это расширение синтаксиса JavaScript, которое позволяет писать структуру интерфейса в виде, напоминающем HTML, прямо внутри JavaScript-кода. JSX используется в React и React Native для описания того, как должен выглядеть пользовательский интерфейс. Несмотря на то, что выглядит как HTML, JSX — это не HTML и даже не шаблонизатор, а способ описания дерева компонентов с помощью синтаксического сахара поверх JavaScript.

Что происходит под капотом: JSX → JavaScript

JSX сам по себе не является исполняемым кодом — браузеры или интерпретаторы JavaScript (например, Node.js или Hermes в React Native) не умеют обрабатывать JSX напрямую. Прежде чем код с JSX можно будет запустить, он должен быть транспилирован (преобразован) в чистый JavaScript.

Для этого используется Babel — транспайлер, который превращает JSX в вызовы React.createElement.

Пример JSX:

const element = <Text>Hello, world!</Text>;

После транспиляции Babel преобразует этот код в:

const element = React.createElement(
Text,
null,
"Hello, world!"
);

Общая структура вызова React.createElement:

React.createElement(
type, // Тип компонента: строка ('div', 'Text') или функция/класс
props, // Свойства компонента (например, { className: 'foo' })
...children // Дочерние элементы
)

Таким образом, JSX просто предоставляет удобный способ записывать структуру компонентов.

Что можно использовать внутри JSX

1. HTML/React-компоненты

JSX позволяет использовать как встроенные компоненты (<div>, <View>, <Text>) так и пользовательские (<MyComponent />).

  • Компоненты с маленькой буквы (div, view, text) интерпретируются как HTML/нативные теги.

  • Компоненты с большой буквы (MyComponent, Header) интерпретируются как React-компоненты.

2. Выражения внутри фигурных скобок {}

Внутри JSX можно вставлять JavaScript-выражения в фигурных скобках:

const name = "Алиса";
&lt;Text&gt;{name}&lt;/Text&gt; // Выведет: Алиса

Допустимые выражения:

  • переменные

  • математические выражения ({1 + 2})

  • функции ({toUpperCase(name)})

  • условные конструкции (в рамках выражений, например name && <Text>{name}</Text>)

Нельзя использовать:

  • инструкции (if, for, while и т.п.)

Особенности синтаксиса JSX

1. Один корневой элемент

JSX-выражение должно иметь один корневой элемент:

Нельзя:

return (
&lt;Text&gt;Hello&lt;/Text&gt;
&lt;Text&gt;World&lt;/Text&gt;
);

Нужно обернуть в контейнер:

return (
&lt;View&gt;
&lt;Text&gt;Hello&lt;/Text&gt;
&lt;Text&gt;World&lt;/Text&gt;
&lt;/View&gt;
);

Или использовать пустой React.Fragment:

return (
<>
&lt;Text&gt;Hello&lt;/Text&gt;
&lt;Text&gt;World&lt;/Text&gt;
&lt;/&gt;
);

2. Атрибуты — в camelCase

JSX использует синтаксис JavaScript, а не HTML, поэтому атрибуты пишутся в стиле camelCase:

  • className вместо class

  • onPress вместо onclick

  • textAlign вместо text-align

&lt;Text style={{ textAlign: 'center', fontSize: 18 }}&gt;
Привет!
&lt;/Text&gt;

3. JavaScript-объекты как значения

Если вы хотите задать объект как значение атрибута, используйте двойные фигурные скобки:

&lt;View style={{ backgroundColor: 'red', padding: 10 }} /&gt;

Первая пара {} — интерполяция JavaScript, вторая — сам объект.

4. Компоненты могут быть функциями

JSX-компоненты можно определять как функции:

function Greeting(props) {
return &lt;Text&gt;Привет, {props.name}&lt;/Text&gt;;
}
&lt;Greeting name="Алиса" /&gt;

Такой компонент можно использовать внутри другого JSX.

5. Дети компонента

Компоненты могут принимать другие компоненты или элементы как children:

&lt;CustomLayout&gt;
&lt;Text&gt;Это содержимое внутри компонента&lt;/Text&gt;
&lt;/CustomLayout&gt;

Внутри CustomLayout можно обратиться к props.children.

JSX и условия

JSX не поддерживает директивы if, но можно использовать тернарный оператор:

{isLoggedIn ? &lt;Text&gt;Добро пожаловать&lt;/Text&gt; : &lt;Text&gt;Пожалуйста, войдите&lt;/Text&gt;}

Или логическое И:

{hasItems && &lt;Text&gt;У вас есть товары в корзине&lt;/Text&gt;}

Для сложной логики можно использовать обычные функции:

function renderContent() {
if (loading) return &lt;ActivityIndicator /&gt;;
if (error) return &lt;Text&gt;Ошибка&lt;/Text&gt;;
return &lt;Text&gt;Данные загружены&lt;/Text&gt;;
}

А затем вызвать в JSX:

&lt;View&gt;{renderContent()}&lt;/View&gt;

JSX и списки

Списки в JSX отображаются с помощью метода map():

const items = \['Апельсин', 'Банан', 'Киви'\];
return (
&lt;View&gt;
{items.map((item, index) => (
&lt;Text key={index}&gt;{item}&lt;/Text&gt;
))}
&lt;/View&gt;
);

Важно: каждый элемент должен иметь уникальный key.

JSX и события

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

&lt;Button title="Нажми меня" onPress={() =&gt; alert('Нажато')} />

События пишутся с заглавной буквы (onPress, onChangeText, onSubmitEditing и др.), и передаётся функция-обработчик.

JSX и вложенность

JSX позволяет строить вложенные структуры:

&lt;View&gt;
&lt;Header /&gt;
&lt;ScrollView&gt;
&lt;Text&gt;Контент&lt;/Text&gt;
&lt;/ScrollView&gt;
&lt;Footer /&gt;
&lt;/View&gt;

Каждый элемент может содержать другие элементы, что позволяет собирать интерфейс из иерархии компонентов.

JSX и функции как элементы

Можно динамически рендерить компоненты, вызывая функции, возвращающие JSX:

function renderHeader() {
return &lt;Text style={{ fontSize: 24 }}&gt;Заголовок&lt;/Text&gt;;
}
&lt;View&gt;
{renderHeader()}
&lt;Text&gt;Тело&lt;/Text&gt;
&lt;/View&gt;

Это позволяет организовать чистый и читаемый код.

JSX в React Native

Хотя JSX в React Native используется почти так же, как в React для веба, есть особенности:

  • Вместо HTML-тегов (div, span, h1) используются нативные компоненты (View, Text, Image и т.д.).

  • Нет className, style работает не с CSS, а с JS-объектами.

  • Вся верстка построена на flexbox, а не на HTML-контейнерах.

JSX и типизация

JSX может использоваться как с обычным JavaScript, так и с TypeScript, что позволяет задавать типы пропсов компонентов, например:

type Props = {
name: string;
};
function Greeting({ name }: Props) {
return &lt;Text&gt;Привет, {name}&lt;/Text&gt;;
}

Это повышает надёжность и масштабируемость кода в больших проектах.