What is JSX in ReactJS and What Does it Do?
ReactJS is without doubt, among the most popular frontend libraries to create the most intuitive UIs, making ReactJS web development services in very high demand. The library is unique for its reusable components and virtual DOM. These features allow us to create complex UIs for our apps. Apps built on ReactJS are very responsive, without a lot of development hassles.
Yet, if you are here to learn about JSX, you already know these. I am taking my chances that you have likely come across JSX too. So without further introduction, let’s get into what is JSX.
What is JSX?
JavaScript syntax extension or JSX is a JavaScript add-on in ReactJS. It enables us to define the object tree of React utilizing syntax akin to an HTML template. We can write JavaScript that resembles markup. Then we can have it returned from a component by simply using an XML-like extension. JSX, as you might be already aware, describes to React what our UI has to look like. You can say it is like a template language, but much more powerful as it is fully supported by JS.
Why JSX?
The inevitable question is, why do we need JSX? Well, as I said, we use JSX to make React understand the components we want on our UI. JSX makes this task simple and elegant for frontend developers. Some of the key benefits of JSX include:
- React can display more helpful errors and warning messages courtesy of JSX.
- It is rather simple to use JSX while creating React applications if one is familiar with HTML.
- Most users find it useful as a visual aid when working with UI inside the JavaScript code, as indicated in the React documentation.
- It is quicker than standard JavaScript. This is because JSX makes optimizations while it converts to standard JavaScript.
- While developing lengthy chunks of code, JSX aids in maintaining the simplicity and elegance of our code.
Features of JSX in React
In this section, we must briefly discuss two important features of JSX in React. These are the prevention of injection attacks and object representation.
Injection Attack Prevention
Before rendering any values encoded in JSX, React DOM escapes those values as a default action. As a result, it guarantees that nothing that has not been clearly stated in our application can ever be injected. Before rendering, everything is transformed into a string. Cross-site scripting (XSS) assaults are thus less likely. This allows us to safely embed user inputs in JSX.
1
2
3
4
5
const title = response.potentiallymaliciousinput;
// This is safe:
const element = <h1>{title}</h1>;
JSX is transpiled into React.createElement()
calls by Babel. To appreciate it better, consider the following two examples. These are identical to others.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
and
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
After performing a few bug checks, React.createElement()
creates an object called React elements. These can be considered as a simple description of what will be viewed on the screen. React uses these objects to create DOMs. You can know more about DOMs in ReactJS.
1
2
3
4
5
6
7
8
9
10
11
12
13
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
Common DOM elements while using JSX in React
- props: These are objects with properties that are supplied to the component and are in React referred to as "props" or null.
- children: This refers to the children we need to pass into the element. The content will be viewed as text if this is a quoted string, as was demonstrated above. We utilize an array for adding several children, and we can nest as many children as we like.
- key: When mapping over arrays, keys specifically distinguish entries among siblings.
- type: The type of React element that will be rendered can be specified using type. A string ("div," "h1"), a React component (class or function), or a React fragment can all be used for this.
- reference: These are pointers to real DOM nodes. They enable you to have immediate access to a DOM element or a component instance.
- $$typeof: Objects are identified as a React element by the property $$typeof. It serves as a defense against XSS assaults (cross-site scripting).
Using JSX
Let us discuss working with JSX at an introductory level using examples.
First, we begin with the simplest known component, rendering ‘Hello World’ in the browser.
It would appear that this component returns HTML, but it does not. The Greet component renders an h1 tag which is a signature JS function call to React.createElement(
). The component would be compiled as:
Any valid JavaScript expression can be embedded after declaring the variable and putting it within curly braces. It is advisable to split JSX over multiple lines for better readability.
So we will first declare a variable to use inside JSX. Let’s call the variable name. We must wrap this variable in curly braces.
1
2
const name = 'Sam Stardust';
const element = <h1>Hello, {name}</h1>;
We can now embed the result of this expression into an <h1> element by calling the formatName(user) JS function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'Sam',
lastName: 'Stardust'
};
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
Note that I used parenthesis while splitting JSX is multiple lines. This is to avoid errors originating from automatic semicolon insertion.
JSX itself can be considered an expression. JSX expressions are converted to standard Js function calls. They are then evaluated to JavaScript objects after compilation.
The fact that JSX itself can be an expression has major significance. We can use JSX in many ways, in if statements, for loops, assign it to variables, take it as arguments, or return it from functions. For example:
1
2
3
4
5
6
7
8
9
10
11
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Greetings to you.</h1>;
}
Specifying Attributes
The type of the React element is specified in the first part of a JSX tag. We use quotes to specify string values and curly braces to specify expressions. Both cannot be specified in the same attribute.
For specifying string literals as attributes, quotes are used like,
1
const element = <a href="https://www.reactjs.org"> link </a>;
For embedding Js expressions in an attribute, curly braces are used like (remember to not use quotes within curly braces),
1
const element = <img src={user.avatarUrl}></img>;
Specifying Children
JSX is syntax sugar for the React function React.createElement(component, props, ...children).
If there are no children, we should use a self-closing form of tags like in XML. Say for example,
If there are no children, we should use a self-closing form of tags like in XML. Say for example,
1
2
3
4
5
6
7
8
9
10
11
<div className="sidebar" />
This would compile into:
React.createElement(
'div',
{className: 'sidebar'}
)
With that scenario covered, how do we then specify when there are children? Check out the example below.
1
2
3
4
5
6
7
8
9
10
11
const element = (
<div>
<h1>Greetings to you</h1>
<h2>I am happy to see you here</h2>
</div>
);
Have you come across an error stating React must be in scope when using JSX?
This error does not happen in React 17 and above versions. This is because Facebook worked together with Babel to upgrade JSX for React 17 to not need Scope. We will talk about how JSX can work without Scope, but let us first see how how it works with it.
JSX works in React 17+ with Babel, a transpiler.
A quick recap on what are transpilers first. These are compilers that convert one type of syntax into another. Babel or TypeScript are examples of transpilers.
Browsers cannot read JSX directly because it is not legitimate JavaScript. For this, we need a transpiler to convert it to React.createElement()
. Hence, to compile JSX into a version that is compatible with browsers, we use transpilers.
The browser is also not likely to be aware that JSX was existent because this takes place during the build phase. A tree of objects that have been specified using the React API is then sent to the browser.
Added to this, specific earlier browsers struggle to understand new features of JavaScript. Particularly those introduced in ECMAScript 6 cause trouble. Transpilers come in handy for converting ES6 to ES5 in these cases.
As we discussed before JSX is compiled into React.createElement()
call. With React in Scope, that is in React 17 or higher, do not have to do this ourselves. Yet, it is possible to use JSX in React even without Scope or importing React library on a top level. As you may have guessed already, we can do this by using a transpiler like Babel (React recommends this), or TypeScript.
It was necessary to include this part in this discussion. This is because only the compiler transform can read the functions listed under react/jsx-runtime
and react/jsx-dev-runtime
. Also, we can continue using React.createElement if you have to manually construct items in our code.
In this blog, we had a comprehensive introduction to JSX and how it is used in ReactJS. We discussed JSX and its benefits, followed by the salient features of JSX in React. We learned that JSX requires to be transpiled for React to read it. Although later versions of React do not make us use a transpiler, older versions of React need them. Certain specific functions also call for transpilers. JSX makes frontend programming using React more elegant and simpler. I hope this discussion helped you to understand and use JSX better.
Sam took the long path into the world of IT. A post-grad in Bioinformatics, she started coding to build better programs for protein sequencing. Currently, Sam actively writes blogs for 4 Way Technologies. She's always excited about all the new technologies and updates in software development. Sam also writes coding tutorials and beginners guides for, well, beginners.