TL;DR

JSX is like a healthy vegetable that tastes like decadent chocolate cake. You feel guilty, but it’s good for you. (Tweet this).

What is JSX?

For those unfamiliar with React, JSX is an inline markup that looks like HTML and gets transformed to JavaScript. A JSX expression starts with an HTML-like open tag, and ends with the corresponding closing tag. JSX tags support the XML self close syntax so you can optionally leave the closing tag off.

JSX expressions evaluate to ReactElements. Think of them as shorthand for calling `React.createElement()`.

Babel has built-in support for JSX. If you need help getting that set up, read “How to Use ES6 for Isomorphic JavaScript Apps.”

Here’s a sample JSX expression for an editable email field:

Let’s break this down:

JavaScript Expressions

You can embed JavaScript expressions in JSX using syntax that will be familiar to any handlebars user, e.g. `style = { displayStyle }` assigns the value of the JavaScript variable `displayStyle` to the element’s `style` attribute.

Styles

You can set styles by assigning an ordinary JavaScript object to the `style` attribute. You don’t use CSS syntax. Instead, you use the similar JS object literal format.

Events

There’s a set of event handlers that you hook up in a way that should look very familiar to anybody who knows HTML.

Inline JSX

The example above looks about the same as a handlebars template, but you usually see JSX expressions mixed with JavaScript:

… and that’s where many developers tune out. At first glance, this looks like the unholy love child of 1990's DHTML and 2015 ES6. We’re talking some Frankenstein madness… right?

Well, not quite. Let’s take a closer look.

JSX is Not an HTML Template Language

Though it looks like it, JSX isn’t a template in the sense that Handlebars and EJS are templates. It’s not a simple token replace and `.innerHTML= foo` dump like so many other tools.

It’s actually a declarative syntax that’s used to express the virtual DOM. JSX gets interpreted and converted to virtual DOM, which gets diffed against the real DOM. Rather than rewrite the whole DOM tree, only the differences get applied. That makes React renders fast.

Additionally, JSX builds in common protections against XSS attacks.

JSX is not limited to HTML. You can use it to create arbitrary object trees. Netflix uses that capability to mirror their web app architecture on a wide variety of devices using their own custom object model for TV rendering.

React Native uses it to render device-native UI elements.

In this sense, JSX is actually a lot more flexible and versatile than a Handlebars template can be.

JSX Event Handlers are NOT Like HTML `onClick`

Despite using the familiar attribute syntax, JSX doesn’t handle events like the same syntax in HTML would.

JSX events get automatically delegated to the root React node. Actually, it goes a step further. It sets up a single event handler on the root node that handles all your events.

What does that mean? Normally when you attach event listeners directly to the element that the user interacts with, you end up with potentially many event listeners in memory for a single page. React creates a single listener automatically, so you never have to think about event delegation again.

This is really great for things like infinite scrolling, because you don’t have to worry about infinitely growing memory consumption (memory leaks).

It looks like DHTML from the 90's, but under the hood, it does the right thing.

TIP: Don’t make the body tag the root node for your React components. Other JavaScript on the page may alter the body tag, and React needs full control over its root element for event management.

Designers Don’t Mind JSX

At first glance, I worried that designers would be scared off by JSX, but I’ve discussed this concern with lots of teams using JSX, and the design teams adjust quickly, and frequently find it easier than working with HTML templates and CSS, which brings up another point…

Inline Styles Are Good

I struggled with this at first. I was all-in on the idea of CSS, but in practice, CSS has failed in a lot of ways. First, it’s essentially a global playground, and CSS selections often overlap in undesirable ways and create awkward side-effects, which leads you to get more specific with the selector, which in turn makes your CSS selections more brittle, so they break when the DOM changes.

Putting styles in a React component is more akin to putting styles in a web component than putting styles into raw HTML. If you did it in raw HTML and you wanted to change the look of a buy button, and you have 10k items, you’d need to update the style in 10k places.

Components don’t work that way. Since the style is in the reusable component, you only have to update it in one place, and you don’t have to worry about selector scoping.

As a bonus, you also get style variables, style modules, style inheritance, and a number of other things you’re already using a preprocessor for — but now you don’t have to learn a whole new syntax. You do it in JS.

I thought I’d hate it, but I love it.

(The Right) Separation of Concerns

React is all about separation of concerns. That may sound surprising coming from a guy who wrote in detail about why business logic and data management should be separated from presentation — but if you’re using React correctly, the only concern you should be worried about is presentation.

React doesn’t deal with data or business modeling. All it does is render stuff efficiently and delegate events. It knows the data it needs to render, it knows when to render it (when the data changes), and it knows how to render it efficiently. Similarly, it knows how to relay UI intentions back to the application.

What it doesn’t know is anything about what the application is doing with those user intentions, or what any of the data means to the business model or business rules.