← Назад к вопросам

Что такое JSX и как он работает в React?

1.0 Junior🔥 171 комментариев
#React

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI21 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое JSX и как он работает в React

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

Что такое JSX

JSX - это XML-подобный синтаксис, который компилируется в обычные JavaScript функции:

// JSX
const element = <h1>Hello World</h1>;

// Компилируется в:
const element = React.createElement(
  'h1',
  null,
  'Hello World'
);

История и мотивация

До JSX разработчики писали React компоненты так:

// Без JSX (очень неудобно)
const button = React.createElement(
  'button',
  { onClick: handleClick, className: 'btn' },
  'Click me'
);

const form = React.createElement(
  'form',
  { onSubmit: handleSubmit },
  React.createElement('input', { type: 'text', name: 'email' }),
  React.createElement('input', { type: 'password', name: 'password' }),
  button
);

const app = React.createElement(
  'div',
  { id: 'app' },
  React.createElement('h1', null, 'Welcome'),
  form
);

Это было очень неудобно. JSX решил эту проблему:

// С JSX (намного удобнее!)
const app = (
  <div id="app">
    <h1>Welcome</h1>
    <form onSubmit={handleSubmit}>
      <input type="text" name="email" />
      <input type="password" name="password" />
      <button onClick={handleClick} className="btn">Click me</button>
    </form>
  </div>
);

Как JSX компилируется

Базовый пример

// JSX
const greeting = <h1>Hello {name}</h1>;

// Компилируется в:
const greeting = React.createElement(
  'h1',
  null,
  'Hello ',
  name
);

С атрибутами

// JSX
const button = (
  <button 
    id="submit" 
    className="btn btn-primary"
    onClick={handleClick}
    disabled={isLoading}
  >
    Submit
  </button>
);

// Компилируется в:
const button = React.createElement(
  'button',
  {
    id: 'submit',
    className: 'btn btn-primary',
    onClick: handleClick,
    disabled: isLoading
  },
  'Submit'
);

С вложенными элементами

// JSX
const list = (
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>
);

// Компилируется в:
const list = React.createElement(
  'ul',
  null,
  React.createElement('li', null, 'Item 1'),
  React.createElement('li', null, 'Item 2'),
  React.createElement('li', null, 'Item 3')
);

С компонентами

// JSX (компоненты с большой буквы)
const profile = <User name="John" age={30} />;

// Компилируется в:
const profile = React.createElement(User, { name: 'John', age: 30 });

// Остальное:
const nativeElement = <div></div>; // React.createElement('div', null)
const component = <User />; // React.createElement(User, null)

Трансформация JSX - React.createElement

// React.createElement сигнатура
React.createElement(
  type,        // 'div', 'button' или компонент (функция/класс)
  props,       // объект с атрибутами, обработчиками, и т.д.
  ...children  // вложенные элементы
);

// Возвращает object
{
  type: 'button',
  props: {
    className: 'btn',
    children: 'Click me'
  },
  key: null,
  ref: null,
  // ... другие свойства
}

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

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

// Условия в {}  работают
const element = (
  <div>
    {isLoggedIn ? (
      <h1>Welcome back!</h1>
    ) : (
      <h1>Please log in</h1>
    )}
  </div>
);

// Можно использовать && оператор
<div>
  {isAdmin && <AdminPanel />}
</div>

// Или ||  оператор
<div>
  {user || <p>No user logged in</p>}
</div>

Циклы через map

// Нельзя использовать for/while внутри JSX
// Используй map, filter и т.д.

const items = [
  { id: 1, name: 'Item 1' },
  { id: 2, name: 'Item 2' },
  { id: 3, name: 'Item 3' }
];

const list = (
  <ul>
    {items.map((item) => (
      <li key={item.id}>{item.name}</li>
    ))}
  </ul>
);

// Или с фильтром
const activeItems = (
  <ul>
    {items
      .filter(item => item.active)
      .map(item => (
        <li key={item.id}>{item.name}</li>
      ))
    }
  </ul>
);

Вычисления в {}

<div>
  {/* Математика */}
  <p>Total: {price * quantity}</p>
  
  {/* Строковые методы */}
  <p>{name.toUpperCase()}</p>
  
  {/* Функции */}
  <p>{formatDate(date)}</p>
  
  {/* Object spread */}
  <Component {...props} />
  
  {/* Ternary */}
  <p>{isOnline ? 'Online' : 'Offline'}</p>
</div>
);

Правила JSX

1. Одного корневого элемента

// ❌ ОШИБКА - два корневых элемента
return (
  <h1>Title</h1>
  <p>Paragraph</p>
);

// ✅ ПРАВИЛЬНО - обернуть в родителя
return (
  <div>
    <h1>Title</h1>
    <p>Paragraph</p>
  </div>
);

// ✅ ИЛИ - использовать Fragment
return (
  <>
    <h1>Title</h1>
    <p>Paragraph</p>
  </>
);

2. Закрывающие теги обязательны

// ❌ ОШИБКА
<input type="text">
<br>
<img src="image.jpg">

// ✅ ПРАВИЛЬНО
<input type="text" />
<br />
<img src="image.jpg" />

3. className вместо class

// ❌ ОШИБКА - class это keyword в JS
<div class="container">...</div>

// ✅ ПРАВИЛЬНО
<div className="container">...</div>

4. Компоненты с большой буквы

// ❌ ОШИБКА - React думает что это HTML тег
return <button />; // OK - встроенный тег
return <myButton />; // ERROR - ищет HTML тег myButton

// ✅ ПРАВИЛЬНО
const MyButton = () => <button>Click</button>;
return <MyButton />; // OK - компонент

5. Атрибуты - camelCase

// ❌ ОШИБКА
<div onclick={handleClick}>...</div>
<input onchange={handleChange} />
<img data-testid="image" />

// ✅ ПРАВИЛЬНО
<div onClick={handleClick}>...</div>
<input onChange={handleChange} />
<img data-testid="image" /> {/* data-* работают */}

Трансформ JSX - разные версии

React 17+ (новая трансформация)

// Не нужно импортировать React!
const element = <div>Hello</div>;

// Компилируется в (без React.)
import { jsx as _jsx } from 'react/jsx-runtime';
const element = _jsx('div', { children: 'Hello' });

До React 17 (старая трансформация)

import React from 'react'; // НУЖНО
const element = <div>Hello</div>;

// Компилируется в
const element = React.createElement('div', null, 'Hello');

JSX это просто синтаксический сахар

// Эти два способа ПОЛНОСТЬЮ эквивалентны

// Способ 1: JSX
function App() {
  return (
    <div className="app">
      <h1>Title</h1>
      {items.map(item => (
        <Item key={item.id} {...item} />
      ))}
    </div>
  );
}

// Способ 2: React.createElement (без JSX)
function App() {
  return React.createElement(
    'div',
    { className: 'app' },
    React.createElement('h1', null, 'Title'),
    items.map(item =>
      React.createElement(Item, { key: item.id, ...item })
    )
  );
}

// Обе функции работают ИДЕНТИЧНО

Практические советы

1. JSX в переменных

const header = <h1>Welcome</h1>;
const footer = <footer>© 2024</footer>;

const page = (
  <div>
    {header}
    <main>Content</main>
    {footer}
  </div>
);

2. JSX функции

function renderWelcome(name) {
  return <h1>Welcome, {name}!</h1>;
}

const greeting = renderWelcome('John');

3. Условные компоненты

function LogoutButton() {
  return <button>Logout</button>;
}

function LoginButton() {
  return <button>Login</button>;
}

function AuthButton({ isLoggedIn }) {
  return isLoggedIn ? <LogoutButton /> : <LoginButton />;
}

Производительность

JSX не влияет на производительность - это просто синтаксический сахар. Важна оптимизация самого React:

// Оба варианта имеют ОДИНАКОВУЮ производительность

// JSX
const element = <div>Hello</div>;

// React.createElement
const element = React.createElement('div', null, 'Hello');

Итого

JSX это:

  1. Синтаксический сахар для React.createElement
  2. HTML-подобный синтаксис в JavaScript
  3. Компилируется в функции во время сборки
  4. Облегчает читаемость кода
  5. Не имеет влияния на производительность (чистый синтаксис)
  6. Основной способ писать React компоненты
  7. Обязателен для modern React разработки

Понимание того, что JSX это просто функции, помогает разобраться со всеми "магическими" моментами React.