JSX в Hyperapp используется как синтаксический слой над чисто функциональной моделью представления, не являясь обязательной частью фреймворка. Hyperapp изначально проектировался так, чтобы работать без JSX, однако поддержка JSX делает описание интерфейсов компактнее и выразительнее, не нарушая принципов минимализма.
В основе Hyperapp лежит функция h, создающая виртуальные
узлы:
h("div", { class: "box" }, [
h("h1", {}, "Заголовок"),
h("p", {}, "Текст")
])
JSX транслируется в вызовы этой функции на этапе сборки:
<div class="box">
<h1>Заголовок</h1>
<p>Текст</p>
</div>
После транспиляции код становится эквивалентным первому варианту. JSX не добавляет новых возможностей, а лишь меняет форму записи.
Для корректной работы JSX требуется указать pragma — функцию, в
которую будет компилироваться JSX. Для Hyperapp это h.
Пример конфигурации Babel:
{
"plugins": [
["@babel/plugin-transform-react-jsx", {
"pragma": "h",
"pragmaFrag": "Fragment"
}]
]
}
Импорт в коде:
import { h } from "hyperapp"
Использование Fragment позволяет группировать элементы
без дополнительного DOM-узла:
<>
<li>Один</li>
<li>Два</li>
</>
Компоненты в Hyperapp — это чистые функции, возвращающие виртуальное дерево:
const Button = (props) => (
<button class={props.primary ? "primary" : ""}>
{props.label}
</button>
)
Компоненты не имеют собственного состояния и жизненного цикла в классическом смысле. Все данные передаются через аргументы, что делает JSX-компоненты предсказуемыми и легко тестируемыми.
JSX напрямую связывается с экшенами Hyperapp:
<button oncl ick={state => ({ count: state.count + 1 })}>
+
</button>
Обработчики событий получают состояние и возвращают новое состояние
или пару [state, effect]. JSX не скрывает эту механику, а
лишь упрощает запись.
Передача аргументов:
<button oncl ick={[increment, 5]}>+5</button>
Где increment — функция-экшен.
JSX не вводит специальных директив. Используются стандартные выражения Jav * aScript:
{state.visible && <Modal />}
или
{state.items.length === 0
? <Empty />
: <List items={state.items} />
}
Такой подход сохраняет прозрачность логики и не требует изучения дополнительных конструкций.
При рендеринге списков ключи указываются через атрибут
key:
<ul>
{state.todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
Ключи используются механизмом диффинга виртуального DOM и напрямую влияют на производительность и корректность обновлений.
JSX в Hyperapp корректно работает с SVG-элементами без дополнительных обёрток:
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" />
</svg>
Атрибуты передаются в исходном виде, без автоматических преобразований, как это происходит в React.
JSX не решает архитектурные задачи и не заменяет модель данных. Он не добавляет:
Все эти решения остаются за пределами JSX и реализуются средствами самого Hyperapp.
hИспользование h без JSX устраняет зависимость от
транспиляции и сборки:
h("button", { onclick: increment }, "+")
Преимущества:
Недостатки:
Этот подход часто используется в средах с жёсткими ограничениями или при написании библиотек.
htmБиблиотека htm предоставляет синтаксис, близкий к JSX,
но без этапа компиляции:
import { h } from "hyperapp"
import htm from "htm"
const html = htm.bind(h)
html`
<div>
<h1>${title}</h1>
</div>
`
Преимущества:
Недостатки:
Вместо JSX можно использовать обычные функции, возвращающие виртуальные узлы:
const view = (state) =>
layout(
header(state),
content(state),
footer(state)
)
Такой стиль подчёркивает композицию и функциональное мышление, жертвуя визуальным сходством с HTML.
JSX в Hyperapp — это удобный, но необязательный инструмент. Он хорошо подходит для:
Альтернативы вроде h или htm лучше
вписываются в минималистичные сценарии и подчёркивают философию Hyperapp
как фреймворка без скрытой магии.