JavaScript vs JSX — What are the Differences?
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.
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>;
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>;
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>;
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"
}
]
}
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>;
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>;
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>;
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
}
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>
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>
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>
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" />
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" />
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>
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" />
</>
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 />
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 />
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" />
As you can see, we are not limited to using the names of HTML attributes only, we can use custom names too.
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'});
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);
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
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!
Rocket Launch Your Career
Speed up your learning progress with our mentorship program. Join as a mentee to unlock the full potential of Webtips and get a personalized learning experience by experts to master the following frontend technologies: