JSX can do that?

Rodrigo Pombo
Hexacta Engineering
3 min readMay 6, 2018

--

First I’m going to explain how JSX works and then use it in “unusual” ways. If you know how JSX works you can skip the first part. If you are here to learn something useful you can skip the second part.

Last week I tweeted this:

People loved it. You can see it in the replies: “Eww”, “what have we done”, “oh no is XML back again”, “Every day we stray further from god’s light”, “murderer”. I write this post to return the love to them (that and also I said to Lorenzo Palmes I’ll write this post if the tweet reached 100 likes, thanks for the retweet Ken Wheeler…).

JSX

If you used React you know JSX, that XML-like syntax for creating React elements:

Because browsers don’t support JSX, your code needs to be changed to normal JavaScript before a browser runs it. This transformation from developer-friendly code to browser-friendly code is done by tools like Babel. Using Babel, the getGreeting function becomes:

Babel REPL

All the tag names, attribute names, attribute values, and text content are still there, with a different syntax. But what about React.createElement?

React.createElement is the function that React uses to create elements. Babel inject that function by default because JSX is commonly used together with React, but that doesn't need to always be the case. In fact JSX is decoupled from React. JSX is a specification for defining tree structures with an XML-like syntax in JS. That tree structure could be the elements rendered by a React component or something entirely different.

In order to use JSX for something different than React, we only need to tell Babel to use another function instead of React.createElement. We do that by adding the comment /** @jsx anotherFunction */ somewhere in the file. For example:

One last thing you need to know is that Babel handles JSX element names in different ways depending if they start with lowercase or with uppercase. Lowercase names are passed as string arguments, like <x/> in the last snippet. Titlecase names are passed as functions, like <Y/> in the snippet.

JSX for Math

Disclaimer: beyond this point you probably won’t learn anything. I’m going to use JSX for things it shouldn’t be used.

We can calculate the hypotenuse of a and b with Math.sqrt(a*a + b*b), but that's no fun. Let's write it with JSX:

codepen

There’s also a version of hypotenuse that can receive more than two arguments:

codepen

JSX for Everything

Let’s try something more ambitious, let’s try merge sort.

We’ll use RamdaJS to have some primitives for our components. This is how FizzBuzz looks in ramda:

Code from stackexchange codereview

We can write the same code using JSX, we only need to write the function that calls the ramda function that matches the JSX element name:

codepen

Beautiful, right?… No.

We can make the run function smarter in order to increase the JSX “purity” of the code:

codepen

Now, anything you can do with ramda you can also do it with JSX. And you can do everything with ramda, including merge sort:

Thanks for reading.

Follow @pomber on twitter for more (awful) stuff like this.

--

--