JavaScript vs JSX — What are the Differences?

JavaScript vs JSX — What are the Differences?

Understanding how JSX works
Ferenc Almasi • 🔄 2022 June 02 • 📖 9 min read

When you start learning React, one of the first things you encounter is JSX, a fundamental way of how you define React components. But what is JSX and how does it compare to JavaScript? In this tutorial, we will uncover everything you need to know about JSX, and what things you need to keep in mind when using it. But first, let's settle what is the core difference between JavaScript and JSX.

JavaScript is a programming language used for adding interactivity to web applications. On the other hand, JSX stands for JavaScript XML. It is a syntax extension for JavaScript that lets you use HTML tags right inside your JavaScript file.

Looking to improve your skills? Check out our interactive course to master React from start to finish.
Master React

What is JSX Exactly?

JSX stands for JavaScript XML. It is a syntax extension for JavaScript that lets you use HTML tags right inside your JavaScript file. Instead of creating, configuring, and appending your HTML tags through JavaScript objects, you can create the elements using an XML-like syntax that will generate the DOM elements for you behind the scenes.

So how does it look like? Let’s see a quick example:

const jsx = <div>Welcome to React</div>;
Just as you would expect, they look and behave like HTML elements.
Copied to clipboard!

How to Use JSX?

So how can you use JSX in practice? JSX is flexible, but they also require certain rules to be followed. Let’s go over its features and rules one by one. First and foremost, you can use JavaScript expressions in JSX.

Using Expressions in JSX

Let’s say you want to use a JavaScript variable in your HTML template. Using curly braces, you can interpolate them to get dynamic behavior:

const name = 'World';
const expression = <h1>Hello {name}</h1>;
Copied to clipboard!

Here {name} will be replaced with the word “World” inside the h1 element. Of course, you can not only embed JavaScript variables but use more complex expressions too:

const a = 1;
const b = 1;
const expression = <code>{a} + {b} = {a + b}</code>;
Copied to clipboard!

This will output 1 + 1 = 2. Expressions are also commonly used for generating a list of HTML elements when working with arrays. Imagine that you have a dynamic menu for which you receive the blueprint from an API:

{
    "menu": [
        {
            "name": "Home",
            "link": "/"
        },
        {
            "name": "About us",
            "link": "/about"
        },
        {
            "name": "Contact",
            "link": "/contact"
        }
    ]
}
response.json
Copied to clipboard!

You can then use a JSX expression to map through the array and display the appropriate elements:

const menu = <ul>{menu.map(item => console.log(item))}</ul>;
Copied to clipboard!

Here we used the Array.map method inside a JSX expression to log each element to the console. But how do we display the list elements?

const menu = <ul>
    {menu.map(item => (
        <li>
            <a href={item.link}>{item.name}</a>
        </li>
    ))}
</ul>;
Copied to clipboard!

We can simply return the required elements from the function. This is equivalent to the following where we explicitly write out the return keyword:

const menu = <ul>
    {menu.map(item => {
        return <li>
            <a href={item.link}>{item.name}</a>
        </li>
    })}
</ul>;
Copied to clipboard!

Expressions can also be used to create if statements or use ternary operators to return different HTML elements based on the value of variables. For these, usually short circuits are used:

{/* If there is a `name` variable, greet the user */}
{name && <h1>Hello {name}</h1>}

{/* The same can be done using a ternary */}
{name
    ? <h1>Hello {name}</h1>
    : null
}
If using a ternary, make sure you return null to tell React to return nothing.
Copied to clipboard!

As you can see, comments in JSX are also used inside expressions. If you were to write // in front of a line, that will be printed out to the final HTML file too, because it is interpreted as a free flow text. Therefore, we need to use expressions when using comments.

Using Attributes in JSX

As we can see, we can also use HTML attributes in JSX elements just as we normally would. You can also use JSX expressions for attributes, or if you are working with a static value, you can use quotes like in regular HTML to define them:

<a href={item.link} target="_blank">{item.name}</a>
Copied to clipboard!

In JSX, these are called props, short for properties. One thing to note is that JSX uses camel case when it comes to attributes that are using dashes. For example, if you were to add aria attributes, you would do:

{/* Invalid */}
<div aria-label="Label"></div>
<div aria-checked="true"></div>
<div tab-index="0"></div>

{/* Valid */}
<div ariaLabel="Label"></div>
<div ariaChecked="true"></div>
<div tabIndex="0"></div>
Copied to clipboard!

There is also a special exception when it comes to using attributes in JSX, and that is using HTML classes. Since the word class is a reserved keyword in JavaScript, we need to use className instead:

{/* Invalid - class is a reserved keyword */}
<div class="carousel"></div>

{/* Valid */}
<div className="carousel"></div>
Copied to clipboard!

Always Close JSX Tags

When you are working with self-closing tags or you use elements that are purely used for conveying visual information and they don’t have any children, make sure you always close them like so, otherwise, you will run into errors:

{/* Invalid - closing tag is missing */}
<br>
<img>
<div>

{/* Valid */}
<br />
<img />
<div className="loader" />
You can use a closing tags for any JSX element
Copied to clipboard!

Returning JSX

Another important rule that we need to point out is that only one JSX element can be returned at a time. What does this mean? Let’s see a practical example. Say you have the following HTML elements:

<span className="tooltip">...</span>
<div className="tooltip-backdrop" />
Copied to clipboard!

This example is invalid as we try to return multiple adjacent JSX elements. In order to fix it, we either need to wrap it inside a parent:

<span className="tooltip-container">
    <span className="tooltip">...</span>
    <div className="tooltip-backdrop" />
</span>
Copied to clipboard!

Or if we don’t want to pollute our DOM tree with unnecessary HTML elements, we can also use a special tag called a fragment:

<React.Fragment>
    <span className="tooltip">...</span>
    <div className="tooltip-backdrop" />
</React.Fragment>

{/* Or */}
<Fragment>
    <span className="tooltip">...</span>
    <div className="tooltip-backdrop" />
</Fragment>

{/* Or */}
<>
    <span className="tooltip">...</span>
    <div className="tooltip-backdrop" />
</>
Copied to clipboard!

All of the three examples above will result in the same code. This will prevent the error from happening, and it won’t add additional DOM elements to your HTML file.

Storing JSX

Last but not least, JSX elements can also be stored in variables and passed around to be used in other JSX elements. However, you will most likely come across cases where JSX elements are stored in functions:

const Slider = () => (
    <div>The HTML layout for the slider</div>
);

// Later in your app, you can reference this function using the function's name:
<Slider />
Copied to clipboard!

Also, make sure that you capitalize your function, otherwise, it will be treated as an HTML element. An exception from this is using object methods, eg:

const component = {
    slider() {
        return <div>The HTML layout for the slider</div>
    }
};

<component.slider />
Copied to clipboard!

By using functions, we can also pass props that we can use for the HTML elements:

const Slider = ({ size }) => (
    <div className={size}>The HTML layout for the slider</div>
);

<Slider size="large" />
<Slider size="medium" />
<Slider size="small" />
Copied to clipboard!

As you can see, we are not limited to using the names of HTML attributes only, we can use custom names too.

Looking to improve your skills? Check out our interactive course to master React from start to finish.
Master React

What JSX is Generated Into?

So what does actually JSX generate into? The browser cannot understand JSX syntax, so React needs to compile it down into JavaScript function calls that the browser can understand. These JavaScript function calls will create and update the necessary HTML elements in the end. Using our first code snippet as an example, it will generate the following function call:

const jsx = <div>Welcome to React</div>;

{/* This will be generated into: */}
React.createElement('div', null, 'Welcome to React');

{/* Using attributes: */}
const jsx = <div className="carousel" />;

React.createElement('div', {className: 'carousel'});
Copied to clipboard!

If the JSX element has children elements, those will also be compiled down to React.createElement calls, therefore in the final JavaScript bundle, you will always see the following blueprint:

React.createElement(component, props, ...children);
Copied to clipboard!

Again, if you use lowercase for components, those will be treated as HTML elements, so make sure you capitalize them:

<component />
React.createElement('component'); // component is not a valid HTML element

<Component />
React.createElement(Component); // the function is referenced

<component.slider />
React.createElement(component.slider); // the method is referenced
How different names are compiled
Copied to clipboard!

Conclusion

Overall, JSX helps you to simplify your code, make it easier to work with, and at the same time, also make it more readable. To recap the important parts of this tutorial, here are some things to keep in mind about the connection of JSX to JavaScript:

  • JSX is a syntax extension for JavaScript that stands for JavaScript XML.
  • React can be written with, or without JSX. Although it is highly recommended to go with JSX for your own sanity.
  • JSX supports the use of expressions by using curly braces.
  • Attributes in JSX are written in camelCase.
  • JSX elements must always be closed. If there are no children elements involved, then elements must be self-closing.
  • Only one JSX can be returned at a time. Use fragments if you need to return multiple elements.
  • Functions can return JSX elements.
  • JSX is generated to React.createElement function calls.

With that being said, now you know everything you need to know about JSX and its correlation to JavaScript. Thank you for reading through, happy coding!

Did you find this page helpful?
📚 More Webtips
Frontend Course Dashboard
Master the Art of Frontend
  • check Unlimited access to hundred of tutorials
  • check Access to exclusive interactive lessons
  • check Remove ads to learn without distractions
Become a Pro

Recommended