All About JSX

What is JSX

JSX is a Markup language used in order to create React elements. The markup can be used to represent a standalone single component or a complex component. The syntax for writing JSX is:

<OpeningTag>...Content...</ClosingTag>
<OpeningTag />

A typical component in React would look like:

<div>This is a div</div> // displays a block of text
<Clock timezone="gmt" /> // displays a clock with the current time

You may be wondering if this looks like HTML, and behaves like HTML, then it must be HTML? Sorry to burst your bubble but its actually JSX, a markup language similar to HTML but actually an extension to JavaScript instead. We will see how it differ from HTML as we pave our way forward in this blog.

JSX and HTML

The creators of React wanted to give the front-end developers a tool that they were familiar with (probably to ease the learning curve), so they ended up going for a markup language similar to HTML. Note that the devs created all the HTML elements (div, main, article, header, footer, etc) into the React library, and the best part is that they all behave the same as they would in HTML.

If we were to display an image in React, we could actually use the same markup that we use in HTML (Nothing hard right? 😲).

<img src="..path_to_img../image.png" alt="This is an image" />

Case Sensitivity

How does React differentiate our custom elements from the HTML elements? It does using case sensitivity. It is recommended that we use Pascal casing for our React components <ReactComponent /> while lower casing for HTML elements <section>...</section> . If we violate these rules, then the React compiler or the developer console will give the following warning:

Warning: reactComponent /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.

Limitations

With great power comes great limitations. Since we are using JSX, a JavaScript extension therefore we are limiting some of the norms of HTML. The typical class attribute used with every element is replaced with className. Similarly the for attribute used in the label element is replaced with htmlFor instead. You may be asking yourself why would the devs do such a stupid change? Well, for and class are JavaScript keywords and therefore cannot be used in JSX.

Furthermore, comments are no longer written as <!-- comment -->, but instead are written like {/* comment */} or {// comment}.

The following are examples of how to use the aforementioned limitations.

<!-- HTML -->
<div id="div" class="abc">This is a div</div>
<label for="div">Label</label>
{/* JSX */}
<div id="div" className="abc">This is a div</div>
<label htmlFor="div">Label</label>

Library Import

At the end of the day, JSX markup’s goal is to create a React element, therefore you must have the React library in scope, otherwise you would get the following error:

'React' must be in scope when using JSX.

resolution:

import React from 'react';

Transpiler

Modern Browsers such as Chrome, Safari or Firefox don’t understand JSX directly, so how does JSX fit into all this? This is where babel comes into play. Babel is a build tool used in your development environment that is used to convert the JSX into pure JavaScript. This allows you to build modern apps using JSX without you having to worry about rendering specifics.

Note: There are other transpilers out there but babel is considered as the defacto standard since it has a lot more features that aid us during developing applications.

“I have the power “ — JSX

As you’ll see the the powers of JSX, it will remind you somewhat of template languages such as EJS, Jade/Pug, Handlebars, etc, but unlike their limited feature set, JSX supports everything JavaScript.

JSX as variables

JSX elements can act as values for identifiers. The following example shows how to declare a variable with a JSX element as the value.

const hello = <h1>Hello, World!</h1>;

Expressions in JSX

JSX supports all JavaScript Expressions by wrapping them inside a pair of curly brackets. The following example displays how to use a primary expression and a combination of object access and function invocation expression.

const name = "Danyal";
const hello = <h1>Hello, {name}</h1>;
const time = "Current time: {Clock.getUserTimeZoneCurrentTime()}";

Similarly, JSX elements are also expressions and can be be used in places such as control statements or loops.

Attributes in JSX

JSX supports attributes the same way as HTML does except for the fact that attributes are written in camelCasing instead of kebab-casing for an attribute that spans multiple words.

<!-- HTML -->
<img src="..path_to_img../img.jpg" accesskey="img" />
{/* JSX */}
const imgSrc = "..path_to_img../img.jpg";
<img src={imgSrc} accessKey="img" />

Props in JSX

The values assigned to each attribute are passed down as properties (props) to the React element. This enhances the power of JSX since they can now handle dynamic data to create React elements. The following example shows how a single Profile component can be used to create multiple dynamic instances.

{/* Creating Profile element using JSX */}
<Profile name="Danyal" bio="I love developing cool apps" />
<Profile name="Pikachu" bio="I love Pokémon as well" />
{/* React Profile Component */}
const Profile = (props) => (
  <section className="profile">
    <h3>Name: {props.name}</h3>
    <p>{props.bio}</p>
  </section>
);

Note: Attributes passed without any value are defaulted as true when received as props <input type="text" disabled />

Conditionally Rendering Components

I’ve already stated that JSX can be used as expressions, this approach comes very handy when we try to render components dynamically.

{/* Creating Profile element using JSX */}

<Profile />
<Profile name="Danyal" />

{/* React Profile Component */}

const Profile = (props) => {
  let heading = null;
  if (props.name) 
    heading = <h1>Hello {props.name}</h1>;
  return {heading};
};

Note: Variables with value of true, false, null and undefined aren’t simply rendered by React.

Behind the Scenes

We have looked at a lot of the cool features supported by JSX, but how does this all work behind the scenes? JSX is nothing more than a syntactic sugar for the React object, an object created in pure JavaScript which holds properties and methods for handling and rendering React elements. You can use the online babel transpiler to check how your JSX code is converted to its equivalent JavaScript code.

Whenever we declare a JSX element, we are actually invoking the React.createElement method. The signature for this method is as:

React.createElement(component, props, ...children);

If we look at a typical example we can see the conversion as:

{/* JSX */}

<p>Hello</p>
<div id="intro">Hello {name}</div>
// JavaScript Equivalent
React.createElement('p', null, 'Hello');
React.createElement('div', {id: 'intro'}, `Hello {name}`);

The reason we don’t work with pure JavaScript is because it is cumbersome when writing nested elements, and the fact that managing large scale applications would be a pain.

{/* JSX */}
<div id="intro">
  <h1>Hello, World</h1>
  <p>This is my world</p>
</div>
// JavaScript Equivalent
React.createElement('div', {id: 'intro'}, 
  React.createElement('h1, null, 'Hello World'),
  React.createElement('p', null, 'This is my world)
);

You can do little bit hand-on on babel here

I hope this helps in understanding JSX How its works !!

Last updated