Что такое JSX и почему он нужен?
JSX (JavaScript XML) — это синтаксическое расширение для JavaScript, которое позволяет писать HTML-подобный код внутри JavaScript-файлов. Он используется в React для описания пользовательского интерфейса и делает код более читаемым и декларативным. JSX не является обязательным для работы с React, но он настолько удобен, что стал стандартом де-факто при разработке на этой библиотеке.
1. Что такое JSX
JSX — это способ описания структуры компонента, похожий на HTML, но при этом интегрированный в JavaScript. Вместо того чтобы писать вызовы функций вроде React.createElement(...) вручную, JSX позволяет использовать привычный HTML-подобный синтаксис.
Пример JSX:
const element = <h1>Привет, мир!</h1>;
Под капотом этот код компилируется в вызов React.createElement():
const element = React.createElement('h1', null, 'Привет, мир!');
JSX можно использовать внутри JavaScript, передавать как значения, вкладывать в переменные, возвращать из функций и т.д.
2. Почему JSX нужен
a. Повышает читаемость кода
JSX позволяет писать UI в декларативной форме, которая интуитивно понятна даже тем, кто не знает React, но знаком с HTML:
return (
<div className="card">
<h2>{title}</h2>
<p>{description}</p>
</div>
);
Без JSX:
return React.createElement(
'div',
{ className: 'card' },
React.createElement('h2', null, title),
React.createElement('p', null, description)
);
Разница в читаемости огромная, особенно при сложной структуре компонентов.
b. Упрощает описание компонентов
JSX объединяет структуру и поведение в одном месте. Это позволяет разработчику видеть, как компонент выглядит и как он работает, не переключаясь между шаблонами и логикой.
c. Позволяет использовать JavaScript внутри разметки
JSX позволяет внедрять JavaScript-выражения в разметку с помощью фигурных скобок:
const name = "Андрей";
const element = <h1>Привет, {name}!</h1>;
Внутри JSX можно использовать любые корректные JavaScript-выражения:
<p>Сумма: {a + b}</p>
<ul>
{items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
d. Поддерживает компоненты как теги
JSX позволяет вставлять React-компоненты как HTML-теги:
function App() {
return (
<div>
<Header />
<MainContent />
<Footer />
</div>
);
}
Имена с заглавной буквы автоматически распознаются как компоненты, а не HTML-элементы.
3. Особенности синтаксиса JSX
a. Только один корневой элемент
JSX требует, чтобы возвращаемый фрагмент содержал только один корневой тег. Нельзя вернуть два соседних элемента без обёртки:
// Ошибка
return (
<h1>Привет</h1>
<p>Мир</p>
);
// Правильно
return (
<div>
<h1>Привет</h1>
<p>Мир</p>
</div>
);
Или можно использовать React.Fragment / <>:
return (
<>
<h1>Привет</h1>
<p>Мир</p>
</>
);
b. className вместо class
Поскольку class — это ключевое слово в JavaScript, в JSX используется className:
<div className="container">...</div>
c. Все теги должны быть закрыты
Даже одиночные, как <img>, <input>, <br>:
<img src="logo.png" alt="Логотип" />
d. Стили указываются через объект
Инлайн-стили в JSX передаются как объект:
<div style={{ color: 'red', fontSize: '18px' }}>Привет</div>
Названия свойств пишутся в camelCase: fontSize, backgroundColor, и т.д.
4. Компиляция JSX (Babel)
JSX сам по себе не понимается браузерами. Чтобы код с JSX работал, он компилируется в чистый JavaScript с помощью транспайлера — чаще всего Babel.
Пример:
const element = <h1>Привет, мир!</h1>;
Компилируется в:
const element = React.createElement("h1", null, "Привет, мир!");
Это делает возможным запуск JSX-кода в любом браузере, поддерживающем JavaScript.
5. Условный рендеринг в JSX
JSX поддерживает условную отрисовку с помощью тернарного оператора, логических выражений и т.д.
{isLoggedIn ? <LogoutButton /> : <LoginButton />}
{showMessage && <p>Сообщение видно</p>}
Также можно использовать функции внутри JSX:
function renderContent() {
if (loading) return <p>Загрузка...</p>;
if (error) return <p>Ошибка</p>;
return <DataComponent />;
}
return <div>{renderContent()}</div>;
6. Использование массивов в JSX
JSX позволяет отображать списки с помощью map:
const users = \['Анна', 'Борис', 'Виктор'\];
return (
<ul>
{users.map(user => <li key={user}>{user}</li>)}
</ul>
);
Каждому элементу списка важно задавать уникальный key.
7. JSX как выражение
JSX — это не строка и не шаблон, а полноценное выражение JavaScript. Его можно присваивать переменной, передавать в функции, возвращать из функций:
const header = <h1>Заголовок</h1>;
function renderHeader() {
return header;
}
Можно использовать в условных операторах, тернарных выражениях, возвращать из компонентов.
8. Отличие от HTML
JSX похож на HTML, но это не HTML. Некоторые важные отличия:
-
class → className
-
for → htmlFor
-
Стили — через объект, а не строку
-
Все элементы должны быть закрыты
-
Атрибуты пишутся в camelCase: onClick, tabIndex, readOnly
9. Безопасность JSX
JSX по умолчанию защищён от XSS (межсайтового скриптинга). Все значения, подставляемые в JSX через {} автоматически экранируются:
const userInput = "<script>alert('взлом');</script>";
return <p>{userInput}</p>; // отобразит как текст, а не выполнит скрипт
Если нужен HTML, нужно использовать dangerouslySetInnerHTML, но его следует применять с осторожностью:
<div dangerouslySetInnerHTML={{ \__html: htmlString }} />
10. JSX помогает использовать силу JavaScript в интерфейсе
JSX позволяет использовать все возможности JavaScript — условия, функции, массивы, объекты, вычисления — прямо в интерфейсе. Это делает компонентный подход React мощным и гибким.