Да, React можно использовать без JSX. JSX — это всего лишь синтаксический сахар для функции React.createElement(). Вся функциональность React доступна и без JSX, хотя код становится более многословным.
Основной способ использования React без JSX:
React.createElement() напрямуюJSX не является обязательным для работы с React. Это просто удобный способ записи, который компилируется в обычные вызовы React.createElement().
// С JSX
const element = <div className="container">
<h1>Привет, мир!</h1>
<p>Это пример с JSX</p>
</div>;
// Без JSX (тот же результат)
const element = React.createElement(
'div',
{ className: 'container' },
React.createElement('h1', null, 'Привет, мир!'),
React.createElement('p', null, 'Это пример без JSX')
);// С JSX
function Welcome({ name }) {
return <h1>Привет, {name}!</h1>;
}
// Без JSX
function Welcome({ name }) {
return React.createElement('h1', null, 'Привет, ', name, '!');
}Вывод: React полностью функционален без JSX, но JSX делает код более читаемым и удобным для написания.
HTM — это альтернатива JSX, которая работает без транспиляции:
import htm from 'htm';
import { h } from 'preact';
const html = htm.bind(h);
// С HTM
function App() {
return html`
<div class="app">
<h1>Привет, мир!</h1>
<p>Это приложение использует HTM</p>
</div>
`;
}
// Без транспиляции!Библиотека для создания DOM-элементов:
import h from 'hyperscript';
// С hyperscript
function App() {
return h('div.app',
h('h1', 'Привет, мир!'),
h('p', 'Это приложение использует hyperscript')
);
}Самодельное решение с шаблонными строками:
function h(tag, props, ...children) {
const element = document.createElement(tag);
// Добавляем атрибуты
if (props) {
Object.keys(props).forEach(key => {
if (key.startsWith('on')) {
// Обработчики событий
element.addEventListener(
key.slice(2).toLowerCase(),
props[key]
);
} else {
// Атрибуты
element.setAttribute(
key === 'className' ? 'class' : key,
props[key]
);
}
});
}
// Добавляем дочерние элементы
children.flat().forEach(child => {
if (typeof child === 'string') {
element.appendChild(document.createTextNode(child));
} else {
element.appendChild(child);
}
});
return element;
}
// Использование
function App() {
return h('div', { className: 'app' },
h('h1', null, 'Привет, мир!'),
h('p', null, 'Это приложение использует шаблонные строки')
);
}Отказ от JSX уменьшает количество зависимостей:
// С JSX требуется Babel и пресеты
// package.json
{
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/preset-react": "^7.0.0"
}
}
// Без JSX можно обойтись меньшим количеством зависимостей
// package.json
{
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}Без транспиляции JSX сборка может быть быстрее:
// webpack.config.js для проекта без JSX
module.exports = {
// Нет необходимости в babel-loader для JSX
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'] // Только JavaScript
// Нет необходимости в '@babel/preset-react'
}
}
}
]
}
};Использование React без JSX помогает понять, как работает библиотека:
// Видно, что происходит на самом деле
const element = React.createElement(
'div',
{ className: 'container' },
React.createElement('h1', null, 'Заголовок'),
React.createElement('p', null, 'Параграф')
);
// Это преобразуется в объект вроде:
/*
{
type: 'div',
props: {
className: 'container',
children: [
{
type: 'h1',
props: {
children: 'Заголовок'
}
},
{
type: 'p',
props: {
children: 'Параграф'
}
}
]
}
}
*/Код без JSX становится значительно длиннее:
// С JSX - компактно и понятно
function Navigation() {
return (
<nav>
<ul>
<li><a href="/">Главная</a></li>
<li><a href="/about">О нас</a></li>
<li><a href="/contact">Контакты</a></li>
</ul>
</nav>
);
}
// Без JSX - многословно и сложно читать
function Navigation() {
return React.createElement(
'nav',
null,
React.createElement(
'ul',
null,
React.createElement('li', null,
React.createElement('a', { href: '/' }, 'Главная')
),
React.createElement('li', null,
React.createElement('a', { href: '/about' }, 'О нас')
),
React.createElement('li', null,
React.createElement('a', { href: '/contact' }, 'Контакты')
)
)
);
}Сложные вложенные структуры становятся трудными для понимания:
// С JSX - структура очевидна
function Dashboard() {
return (
<div className="dashboard">
<header>
<h1>Панель управления</h1>
<nav>
<ul>
<li><a href="#profile">Профиль</a></li>
<li><a href="#settings">Настройки</a></li>
</ul>
</nav>
</header>
<main>
<section>
<h2>Статистика</h2>
<div className="charts">
<div className="chart">График 1</div>
<div className="chart">График 2</div>
</div>
</section>
</main>
</div>
);
}
// Без JSX - сложно понять структуру
function Dashboard() {
return React.createElement(
'div',
{ className: 'dashboard' },
React.createElement(
'header',
null,
React.createElement('h1', null, 'Панель управления'),
React.createElement(
'nav',
null,
React.createElement(
'ul',
null,
React.createElement('li', null,
React.createElement('a', { href: '#profile' }, 'Профиль')
),
React.createElement('li', null,
React.createElement('a', { href: '#settings' }, 'Настройки')
)
)
)
),
React.createElement(
'main',
null,
React.createElement(
'section',
null,
React.createElement('h2', null, 'Статистика'),
React.createElement(
'div',
{ className: 'charts' },
React.createElement('div', { className: 'chart' }, 'График 1'),
React.createElement('div', { className: 'chart' }, 'График 2')
)
)
)
);
}Без JSX теряется часть статической проверки ошибок:
// С JSX - ошибки выявляются на этапе компиляции
// <div class="container"> // Ошибка: должно быть className
// <p>Параграф</p>
// <!-- Незакрытый тег --> // Ошибка: незакрытый тег
// </div>
// Без JSX - ошибки могут остаться незамеченными
const element = React.createElement(
'div',
{ class: 'container' }, // Ошибка не выявляется сразу
React.createElement('p', null, 'Параграф')
// Пропущен закрывающий элемент
);Для понимания внутренней работы React:
// Отличный способ понять, как работает Virtual DOM
function createElementDemo() {
const element = React.createElement(
'button',
{
onClick: () => console.log('Кнопка нажата'),
style: { backgroundColor: 'blue', color: 'white' }
},
'Нажми меня'
);
console.log(element); // Видим структуру Virtual DOM
return element;
}Когда нужно минимальное количество зависимостей:
// Минимальный React-приложение без JSX
import { createRoot } from 'react-dom/client';
function App() {
return React.createElement(
'div',
null,
React.createElement('h1', null, 'Минимальное приложение'),
React.createElement('p', null, 'Без JSX и дополнительных зависимостей')
);
}
const root = createRoot(document.getElementById('root'));
root.render(React.createElement(App));В средах, где нет возможности настроить транспиляцию:
// В браузерной консоли или CodePen без Babel
// Можно использовать React напрямую
const element = React.createElement(
'div',
{ style: { textAlign: 'center' } },
React.createElement('h1', null, 'Привет из консоли!'),
React.createElement('p', null, 'React без JSX')
);
ReactDOM.render(element, document.getElementById('app'));Для упрощения кода можно создать вспомогательные функции:
// Вспомогательная функция для создания элементов
function h(type, props, ...children) {
return React.createElement(type, props, ...children);
}
// Упрощает написание кода
function App() {
return h('div', { className: 'app' },
h('h1', null, 'Заголовок'),
h('p', null, 'Параграф'),
h('button', { onClick: handleClick }, 'Кнопка')
);
}Для улучшения читаемости можно использовать объекты:
// Вместо длинных списков параметров
const buttonProps = {
className: 'btn btn-primary',
onClick: handleClick,
disabled: isLoading,
style: { marginTop: '10px' }
};
const element = React.createElement(
'button',
buttonProps,
isLoading ? 'Загрузка...' : 'Отправить'
);Для часто используемых элементов:
// Фабричные функции для часто используемых элементов
const div = (props, ...children) => React.createElement('div', props, ...children);
const button = (props, ...children) => React.createElement('button', props, ...children);
const input = (props) => React.createElement('input', props);
// Упрощает использование
function Form() {
return div({ className: 'form' },
input({ type: 'text', placeholder: 'Имя' }),
input({ type: 'email', placeholder: 'Email' }),
button({ onClick: handleSubmit }, 'Отправить')
);
}React можно использовать без JSX, и это может быть полезно в определенных ситуациях:
✅ Когда это уместно:
❌ Когда лучше использовать JSX:
Ключевые моменты:
React.createElement()Понимание возможности использования React без JSX помогает глубже понять библиотеку и принимать более обоснованные решения при выборе инструментов для проекта.
Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪