I've been using frameworks and libraries with a virtual DOM for a while now (specifically, React, Cyclejs and Hyperapp), and many people using them seem to prefer jsx over hyperscript-like helpers.
Back when I first started using React, I really liked jsx because it is close to HTML and more powerful than any templating language I know of. For anything you can't do with regular HTML syntax, you can just drop a couple of brackets and write Javascript code.
But then I discovered hyperscript-like helpers, which allowed me to create vdom elements using plain Javascript functions with names like div(...)
, and I immediately fell in love with that approach.
To compare some code:
// JSX
<div class="container">
<h1>Ponies</h1>
<PonyList>
{ ponies.map(({ name, type }) => <PonyItem name="name" type="type"/>) }
</PonyList>
</div>
// Hyperscript
div({ class: 'container' }, [
h1('Ponies'),
PonyList(
ponies.map(({ name, type }) => PonyItem({ name, type }))
)
])
Both are easy to read. The first word in the line tells you which HTML element or component you are creating. Jsx looks more like HTML, which we are used to. However, the more dynamic behaviour we want, the more Javascript code we have to inline. On the other hand, we don't need any special syntax for hyperscript-helpers and everything is just regular Javascript.
For the record, jsx still trumps having to create elements with React.createElement
, but there are hyperscript alternatives for React too.
From my perspective, both approaches are more than good enough, but I don't see why I would prefer jsx over plain Javascript, since it doesn't seem to provide any extra benefit.
My question then is, why would you prefer jsx over hyperscript? Does it provide any advantages I'm unaware of?
With a simple example you will not see much of a difference indeed, but I would not use the second version in a bigger project.
One of the reason would be that is too abstract and less verbose and will lead to a lot of extra code when doing something custom. If I just want to add a simple
<i class="me"></i>
I do not want to define it as a function, send a parameter and so on, I just want to insert a HTML snippet, as it is.The reverse applies too, looking more like the end product (HTML), the first solution is easier to understand when things get bigger. The overhead is bigger in Hyperscript, you need to stack all the calls in your head and compile it to HTML to understand it.
Hyperscript looks like Flutter/Dart, and there I guess makes more sense, first of all you don't have HTML and you have strong typed objects.