React and JSX: The Importance of HTML Knowledge blog post

React and JSX: The Importance of HTML Knowledge

Almero Steyn

16 Aug, 2019

React

9 minutes read

When I first encountered JSX it was a bit of a shock. After years of separating HTML templates, we landed upon JSX and were suddenly enlightened to the idea of "mixing" our HTML and JavaScript to build in a more functional style.

Without getting into the whole "HTML in JS" debate, I’m here to unravel some key points for you so you can focus on learning and perfecting your HTML knowledge alongside JSX – and most importantly recognise and know the differences between them.

I still remember reading the words "Just give it a try!" somewhere and decided to dive in. I’m super happy that I did – what I found was a pleasant surprise for me.

It was hard to shed the idea that JSX was "HTML in JavaScript" but that was the first step in realising the development power it contained (especially if you’ve done any templating with ES6 String Literals and Functions).

Remember: JSX is just JavaScript.

Let’s consider the following JSX:

<button type="button">Delete</button>

Wait, JSX? How could this possibly be JavaScript? It looks exactly like HTML!

Remember, even when we write modern versions of JavaScript (such as ES6 or TypeScript) the code executed by the browser isn’t the ‘source’ code that we write. Newer features in these modern versions of JavaScript enables us to write more powerful and expressive code. This code is then translated, or transpiled, into JavaScript that a browser can understand and execute.

The same is true for JSX.

Browsers don’t understand how to process HTML if we write it directly in JavaScript – because it’s technically not valid JavaScript code. Think of JSX as JavaScript, plus some extra syntax that allows us to write HTML inside it.

So, back to our code. When it’s passed through a transpiler, the above JSX is translated to the following code:

React.createElement('button', { type: 'button' }, 'Delete');

Now it’s valid JavaScript, using the React.createElement method available on the React object.

Like TypeScript, JSX is another extension on JavaScript that allows us to code in a more ergonomic way. Writing browser view in HTML has been the staple of most developers who built the web we know today and therefore it made sense to continue using this well known syntax even when writing view in JavaScript.

In fact, every HTML element has an equivalent JSX element we can use!

But does JSX look exactly the same as HTML? No. There are some subtle differences that can be summarised as:

  • Element props in JSX are written in camelCase but the related attributes in HTML are not. So in HTML we have the maxlength attribute but in JSX the equivalent prop will be maxLength. Because we are in the JavaScript land when we write JSX the same naming conventions apply. It also saves us doing strange naming conversions in our code when referring to props.
  • While HTML allows unclosed tags such as <input>, JSX does not and all tags should be closed, for examples <input/>.
  • The class attribute becomes className, as class is a reserved keyword in JavaScript. This is probably one of the most common gotchas.
  • The for attribute used on <label> becomes the htmlFor prop as for is a reserved keyword in JavaScript.

Understanding the relation between HTML and JSX is key to the power that JSX gives us. The declarative syntax of HTML combined with the power of JavaScript gives us a really nice recipe for composing component templates with data.

The problem with power is that it can be abused if the correct decisions aren’t made, and I’m here to help you make the right ones.

Let’s consider the following:

<div className="looks-like-a-button" onClick={onClickHandler}>
  Save
</div>

It is pretty easy to make interactive elements in the browser using JSX and React. A quick <div> with an attached onClick handler, then style it to look like a button and we have a button, right?

The straight answer is that we don’t.

We created a clickable container element that can be activated with the mouse alone.

The truth is that many people rely on the keyboard as sole input device to navigate the web, either through choice or because they are unable to use a mouse at all.

The secrets of supporting users who rely on the keyboard alone is called is called keyboard accessibility and while we won’t dive very deep here, we will briefly focus on using the TAB key to navigate interactive elements as well as an important demographic relying on the keyboard, namely screen reader users.

Learn more about keyboard accessibility by WebAIM, I’d highly recommend it to every developer.

So why is our <div> button solution not good enough? Let’s investigate.

Consider two things:

  1. Keyboard users typically select interactive elements, such as buttons, using the TAB key on the keyboard and as the <div> element is not interactive by default the "button" cannot be accessed at all.
  2. Users who can see the screen get a visual cue that this element is supposed to be a button via the applied styled. On the other hand, screen reader users typically cannot see the screen at all or well enough to navigate with a mouse. With a native <button> element the screen reader would announce it as a button, but this does not happen with a <div> leaving this group of users in the dark about what the element is supposed to do or how to interact with it.

Both these issues are solved by using the native HTML <button> element or, translated to JSX, using the equivalent JSX <button> element.

<button onClick={onClickHandler}>Save</button>

Let me emphasise: these are not React concepts at all! They exist in HTML and understanding how browsers present the UI information, because the browser is the actual interface between the pages we create and either people or assistive technology software such as screen readers.

Our <div> illustrates this. It does not fail not because React failed, but because of how we instructed the browser to draw the button.

So, is core knowledge of HTML still required in the age of React and JSX?

Most certainly yes!

Understanding how the browser exposes the functionality we build in JSX to people who are meant to use it is key as this takes the guesswork out of writing React code that renders a usable result every time.

Does that mean we shouldn’t create custom elements? Thankfully the answer is no, but when we create our own elements out of non standard elements, we have to know EVEN MORE about HTML.

Let’s return to our <div> button. Is it possible to turn this into a button element that is indistinguishable to the native <button> element as far as users of the application is concerned? Yes! But it comes at a cost (and we thought buttons were simple!).

FIRST we have to know how the <button> element was implemented in the browser, because buttons:

  • Are focusable by the keyboard
  • Have default "button" styling
  • Act as buttons to both people as well as software such as screen readers or search engine crawlers
  • Can be activated by clicking, touching or pressing the Enter or Space keys on a keyboard

Fun fact with buttons: Enter activates the button on keydown while Space activates it on keyup!

So, now we know how it works, we can cover these points by:

  • Adding a tabIndex value of 0
  • Adding CSS to make it look like a button
  • Adding a role of button
  • Adding an onKeyDown handler that triggers the button on Enter
  • Adding an onKeyUp handler that triggers the button on Space

Which means our JSX becomes something along the lines of:

<div
  tabIndex="0"
  className="looks-like-a-button"
  role="button"
  onKeyDown={onKeyDownHandler}
  onKeyUp={onKeyUpHandler}
  onClick={onClickHandler}
>
  Save
</div>

Plus we need to code the extra two event handlers functions! Putting it all together, give this a try!

Let me stress, this button acts exactly as a button should in the true sense of the word. It is indistinguishable from the <button> element. So if you have a deep understanding of the HTML specification as well as the ARIA specification and create elements out of <div> for good reason, please continue to do so. This article by no means intend to say that properly implemented solutions are not accessible.

It’s interesting to note that deviating from standard HTML in the browser actually requires MORE knowledge of HTML!

Regardless of how we look at it, having at least a baseline knowledge of HTML remains as relevant in the days of React and JSX as before.

As our development tools become more powerful and increases the separation between the code on our screen and the result in the browser, increasingly treating the HTML and rendered DOM in the browser as implementation detail rather than the actual UI we are rendering comes at a great cost.

Our now notorious <div> button example is by no means an isolated incident. It extends to all reaches of our applications such as knowing how to label our form controls, how to display list, how to demarcate the regions of our pages in a way that screen reader users can easily navigate around large blocks and the list goes on.

The secrets on how to achieve all this and more is waiting to be discovered in HTML itself. When you come back to JSX you will find all those features ready and waiting to be used in your next React application.

Want to learn more? I’m working on React Courses that will deep dive JSX, component architecture, new Hooks APIs and so much more. See you there!

About the author

Almero is a freelance front-end engineer, speaker and trainer specialising in React. He wrote the accessibility section in the React docs and loves to build websites all humans can use. Having most recently fallen in love with Gatsby, this ingredient can be found in many of his most recent projects. When not coding Almero reads, cycles or explores historical sites in Europe.

Love the post? Share it!

Lots of time and effort go into all our blogs, resources and demos,
we'd love it if you'd spare a moment to share them!

Explore our React courses

Get started today and join over 60,000 developers.