loading...

Why do you like jsx?

avalander profile image Avalander ・2 min read

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?

Discussion

pic
Editor guide
Collapse
bgadrian profile image
Adrian B.G.

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.

Collapse
avalander profile image
Avalander Author

Thanks for your input!

Could you elaborate on how hyperscript leads to extra code? I don't see much difference between adding <i class="me"></i> or i({ class: 'me' }) in the view code.

Collapse
bgadrian profile image
Adrian B.G.

In this example the extra code is the function named i and the code that handles its properties

Thread Thread
avalander profile image
Avalander Author

The function i would normally be provided by whatever hyperscript library you're using, it's not like you need to implement a new function for each html element that you decide to use.

Thread Thread
bgadrian profile image
Adrian B.G.

In this example yes, but it does not matter who wrote the function, is extra JS code that does not carry its weight. It does not add any benefit, it is just syntax sugar. It is extra code that runs on VM, is downloaded and you have to learn it.
It is not ebough to learn html, you have to learn what elements are in hyperscript as functions, again, a layer of useless complexity in the developers head.

Thread Thread
denisinvader profile image
Mikhail Panichev

But JSX also compiles into javascript functions, doesn't it?

Thread Thread
martinhaeusler profile image
Martin Häusler

As far as I know, JSX compiles to only one function, the h function (or hyper function). The type of element you create is actually passed as the first argument as a string to this function. Therefore, as long as you only create built-in HTML elements (and not, let's say, custom react components) there are no additional functions involved.

The h-function takes three parameters:

  • The name/type of the element as a string
  • The properties of the element as an object
  • An array of child elements, in turn produced by the h function

So, this example:

<span><i>Hello!</i></span>

would compile to something like this:

h('span', {}, [ h('i', {innerHTML: 'Hello!'}, []) ] )

Thread Thread
denisinvader profile image
Mikhail Panichev

sounds reasonable:)

Collapse
artemis profile image
Diane

I also personally prefer the Hyperscript-like syntax over Jsx, especially since it can be done with plain javascript, without any build tool.

On the likings, there's the awesomely lightweight UI framework called Mithril.Js, which have a similar syntax.

Collapse
avalander profile image
Avalander Author

I heard about Mithril a while ago, but i never tried it, is it any good?

Collapse
artemis profile image
Diane

I find working with it a real breeze.

Even when something is not very nicely documented in the guide, the API doc is really complete, and since the API is really dead simple, it's really easy to understand.

I used it on my portfolio, for the contact form, whose source can be found here. The code isn't the prettiest of the codes because I kinda did it "quickly", but it works nicely.

Collapse
vonheikemen profile image
Heiker

I believe that there is some benefit in JSX.

One thing would by familiarity. Is close enough to HTML to make it kinda comfortable? I mean, when you see div in JSX is almost the same as in HTML.

The end and the beginning of a component in the render function is painfully explicit. You could find the opening tag and the closing tag even with bad indentation.

With JSX you could also migrate some old HTML to a component with little effort.

That said. I actually don't like JSX. It just bugs me.

Collapse
roshan092 profile image
roshan092

Thanks for the question, heard about hyperscript first time today hence I cannot answer which one is better.
I have used JSX a lot and the main factor that convinced me to keep using this was the IDE support (Intellij).

Collapse
whoisryosuke profile image
Ryosuke

It just looks better and makes code easier to read.

Rather than looking at my components as functions, they're more like DOM elements, making them easier to intermingle with other elements (or shift around the tree).

Collapse
kepta profile image
Kushan Joshi

You should also look at the official explanation behind usage of JSX at reactjs.org/docs/introducing-jsx.h...

Collapse
levitabris profile image
Wei Li

Can I ask a stupid question? Which one is easier to debug? For instance, if there is mistyped variable name, which solution gives me the most friendly message to track down that error source? Thanks!

Collapse
avalander profile image
Avalander Author

Well, jsx is transpiled to plain JavaScript function calls, so both jsx and the equivalent hyperscript will result in the same error message.

Collapse
levitabris profile image
Wei Li

Helpful explanation, thanks.