JSX Tutorial: Complete Guide to React's JavaScript Syntax Extension
Master JSX, the syntax extension for JavaScript that makes writing React components more intuitive and efficient.
A React component is a Javascript
function starting with a capitalized letter and returning an Html-like Markup
known as JSX
.

Introduction
JSX
is considered a syntax extension for Javascript
. Yes you heard it right, it’s a syntax extension for Javascript
and not for Html
as many people think.
Meaning that, the JSX
is converted to valide Javascript Code 😮.
Under the hood, the conversion is done by compilers like Babel
or SWC
. Consequently the whole component tree representing our App get converted into Javascript
objects that can be understood by the browser and used by the React
runtime to render the final Html
code.
For example the code bellow.
function Image() {
return <img alt="Blog post image" src="https://picsum.photos/500/400" />;
}
function App(){
return (
<Image/>
)
}
will get converted to:
import { jsx as _jsx } from "react/jsx-runtime";
function Image() {
return /*#__PURE__*/_jsx("img", {
alt: "Blog post image",
src: "https://picsum.photos/500/400"
});
}
function App() {
return /*#__PURE__*/_jsx(Image, {});
}
the role of the
_jsx
function is to build and return the object representing theJSX
node.
So instead of writing all of that, we use JSX
for its conciseness. It’s easier to write and looks mostly like the final Html code
that will get shipped into the user’s browser.
In this article, we will see why it’s even a good idea to co-locate the markup with its corresponding Javascript
logic in a single place — React
component.
Then we will question What makes JSX
different from ordinary Html code
?
And finally we are going to understand how to use JSX
code correctly and connect it with the component’s javascript logic using the magical curly bracket syntax {}
.
So if that sounds interesting let’s dive in.
Why Co-locate Markup and Logic?
In traditional or Vanilla
Javascript
, the Markup
and the Javascript
logic live in separate files. That was totally fine when most of the applications were mostly relying on server side logic with minimal interactivity.
As the years have rolled by, the world understood the psychological and business benefits of User experience or UX; hence, the need for more interactive and engaging websites.
An example For that is a welcome component which only gets displayed when the user is logged in
function Welcome() {
const isLoggedIn = true;
if (!isLoggedIn) {
return null;
}
return <h1>Welcome back!</h1>;
}
If the user is not logged in we just return null if it’s logged in we display this welcome message.
The fact that a component is its own block of Markup plus Logic ensures that changes to either of the two are always synced together.
In traditional web pages the whole Html
is stored in a single file. Consequently changing one line may break the whole page.
But that’s not the case for React
, because every component has its own Markup
. So modifying a component’s Markup
may only break the component itself with only the other components that depend on it but not the whole page.
JSX vs HTML: Key Differences
Okay, Next let’s compare between Html
and JSX
.
The syntax is almost the same but JSX is more strict.
First Rule
So the first rule consist of always closing the tags in JSX
including self closing tags like <img/>
or wrapping tags like <div>
s.
function App(){
return (
<div> // ✅
<img> // ❌
<img/> // ✅
</div> // ✅
)
}
Second Rule
The second rule states that attributes expect these two special ones (data-, and aria-) and component names should be always written in camel case.
function my_component(){/*...*/} // Snake case ❌
function MyComponent(){/*...*/} // Camel case ✅
<button tab-index={0}> </button> // Kabab case ❌
<button tabIndex={0}> </button> // Camel case ✅
It’s also worth mentioning that Attribute names like class
that comes to be reserved keywords in the Javascript
language are not allowed. So instead of class
you write className
.
<div class="..."> </div> // ❌
<div className="..."> </div> // ✅
Third Rule
The third important rule is that you can’t return a bunch of children tags without wrapping them in a parent root element.
Remember that JSX
get transpiled or converted into a plain Javascript
object. So as you can’t return multiple objects from a single function without wrapping them in an array or a parent object, you also can’t just return a bunch of children tags without wrapping them in a root
element like a div
or any other JSX
tag.
function invalidFunction(){
return {key:"sidali"}, {key:"I don't know"}; // ❌
}
function validFunction(){
return [{key:"Neovim"},{key:"Btw"}]; // ✅
}
Using a div
as a wrapper can be annoying sometimes, especially when styling elements. Instead there is a built-in React
alternative which you can use.
It’s the fragment component: so you can either wrap your component in a Fragment component imported from react, or just use the concise syntax which consist of an empty tag element <>wrapped content here...</>
.
function IncorrectComponent(){ // ❌
return (
<h1>Title</h1>
<div>Description </div>
)
}
import React from 'react'
function CorrectComponent1(){ // ✅
return (
<React.Fragment>
<h1>Title</h1>
<div>Description </div>
</React.Fragment>
)
// Or more concisely
function CorrectComponent2(){ // ✅
return (
<>
<h1>Title</h1>
<div>Description </div>
</>
)
Using JavaScript in JSX
Sure we can perform any kind of Javascript
logic in the function’s body before returning the JSX including if statements, for loops and so on.
But is there a built-in way to use Javascript
or reference a Javascript
value or object from within the JSX
code itself?
Yes, and it’s pretty simple just use the curly bracket syntax {}
and then reference any variable, value, function or expression from the Javascript world 🌎
.
So instead of hard coding the title value in the Markup
here, we can store the h1
tag inner content in a Javascript
variable as a string.
And then reference it in the Markup
, using the curly bracket syntax like this.
function App(){
const title = "This is my first react component";
return (
<div>
<h1>{title}</h1>
<ol>
<li>Wake up</li>
<li>Code</li>
<li>Eat</li>
<li>Sleep</li>
<li>Repeat</li>
</ol>
</div>
);
}
You can think of the curly brackets {}
as a Javascript
return statement, so any Javascript
expression which outputs something is valid to use within the curly brackets {}
.
So instead of hardcoding the h1
tags, we could have created a createTitle
arrow function which takes a title and then returns it wrapped within h1 tags.
Subsequently, we can use it inside the Markup
by employing the curly brackets syntax {}
, then calling the function that returns the JSX
.
function App(){
const title = "This is my first react component";
const createTitle = (title) => <h1>{title}</h1>;
return (
<div>
{createTitle(title)}
<ol>
<li>Wake up</li>
<li>Code</li>
<li>Eat</li>
<li>Sleep</li>
<li>Repeat</li>
</ol>
</div>
);
}
As you can see, JSX
can be stored normally in a Javascript
variable, and then rendered in the Markup
later.
Keep in mind that, You can store any JSX
code in a Javascript
variable following the same rules which you normally follow within the Return ()
statement.
Remember that The brackets are optional unless your JSX
code spans more than one line.
const var1 = <h1>This is my first react component</h1>;
const var2 = (
<div>
{var1}
<ol>
<li>Wake up</li>
<li>Code</li>
<li>Eat</li>
<li>Sleep</li>
<li>Repeat</li>
</ol>
</div>
);
You can use the curly bracket syntax to set any attribute into a string
, let’s say the className
attribute.
Other attributes like style
require passing an object
, including your inline css code in camel case instead of kebab case as you used to do in normal Html
or CSS
code.
/* CSS kebab-case */
background-color: black;
color: pink;
function App(){
const title = "This is my first react component";
const createTitle = (title) => <h1>{title}</h1>;
const classNameValue = "class1 class2";
const style = {
backgroundColor: 'black',
color: "pink"
};
return (
<div className={classNameValue} style={style}>
{createTitle(title)}
<ol>
<li>Wake up</li>
<li>Code</li>
<li>Eat</li>
<li>Sleep</li>
<li>Repeat</li>
</ol>
</div>
);
}
Many get confused with the double curly brackets {{}}
, when passing the style object directly like this.
<img style={{backgroundColor:'red'}}/>
Thinking that it’s a special JSX
syntax, but in fact it’s not we are just passing a normal Javascript
object
within the curly bracket syntax.
function App(){
const styleObj = {backgroundColor:'red'}
return(
<img style={styleObj}/> // Instead of style={{backgroundColor:'red'}}
)
}
Conclusion
So that was it for JSX
, in the next article we will learn about a new way that allows us to make React
components more generic and reusable while allowing bidirectional data flow from parents component to their direct or indirect children.
Let me know in the comment sections below if you have any questions or thoughts about the article. Thanks for your attentive reading and happy coding.