What Is JSX?
JSX (JavaScript Syntax Extension or JavaScript XML) is an extension to JavaScript. It provides an easier way to create UI components in React. Here’s an example of its syntax:const element = <h1>Hello, World!</h1>;
What comes after the equals sign isn’t a string or HTML, rather JSX. It doesn’t render out to HTML directly but instead renders to React Classes.
JSX is what we call Syntactic Sugar. A syntax created purely to programming easier to read and write for the developer – to make life sweeter. Under the hood JSX is simply turning the above code into a much more verbose class using the traditional React.createElement((component, props, ...children)))
method:
React.createElement(
"h1",
null,
"Hello, World!"
)
)
JSX isn’t only recommended by the React team because it saves you time. It was also created to help combine markup and logic into components, work with TypeScript to provide stricter data typing, and improve security.
How Does It Work?
JSX is still just JavaScript with some extra functionality. With JSX, you can write code that looks very similar to HTML or XML, but you have the power of seamlessly mixing JavaScript methods and variables into your code. JSX is interpreted by a transpiler, such as Babel, and rendered to JavaScript code that the UI Framework (React, in this case) can understand. Note: you can use the Babel REPL to convert any of the following examples to regular JavaScript. Don’t like JSX? That’s cool. It’s technically not required, and the React docs actually include a section on using React Without JSX. Let me warn you right now, though, it’s not pretty. Don’t believe me? Take a look. JSX:class SitePoint extends Component {
render() {
return (
<div>My name is <span>{this.props.myName}</span></div>
)
}
}
React Sans JSX:
class SitePoint extends Component {
render() {
return React.createElement(
"div",
null,
"My name is",
React.createElement(
"span",
null,
this.props.myName
)
)
}
}
Sure, looking at those small example pieces of code on that page you might be thinking, “Oh, that’s not so bad, I could do that.” But could you imagine writing an entire application like that?
The example is just two simple nested HTML elements, nothing fancy. Basically, just a nested Hello World
equivalent. Trying to write your React application without JSX would be extremely time consuming and, if you’re like most of us other developers out here working as characters in DevLand™, it will very likely quickly turn into a convoluted spaghetti code mess. Yuck!
Using frameworks and libraries and things like that are meant to make our lives easier, not harder. I’m sure we’ve all seen the overuse and abuse of libraries or frameworks in our careers, but using JSX with your React is definitely not one of those cases.
Why Use JSX?
There are several reasons why JSX is a good idea: It has a low barrier to entry. JSX is as close to plain HTML and CSS as it currently gets. With JSX, you can easily embed pieces of JavaScript in your templates without having to learn an additional templating language and having to deal with complex levels of abstraction. Any person familiar with HTML, CSS, and JavaScript should have no problem reading and understanding JSX templates. TypeScript support. TypeScript supports the compilation of TSX files with type-checking. This means that, if you make a mistake in the name of an element or an attribute type, the compilation will fail and you’ll see an error message pointing to your mistake. Popular IDEs such as VS Code also support TSX files and provide code-completion, refactoring, and other useful features. Security. JSX takes care of the usual output sanitization issues to prevent attacks such as cross-site scripting.What about a Separation of Concerns?
There’s a widespread belief that mixing HTML and JavaScript breaks the sacred separation of concerns principle. This judgment assumes that there’s a clear separation between HTML — which is responsible for the presentation — and JavaScript — which is responsible for application and business logic. However, this separation is based on technology, not on their concerns. JavaScript that’s responsible for rendering a list of items still belongs to the presentation layer and should be kept closer to the template than to the rest of the application. By using JavaScript, we embrace the fact that the border should be drawn not between HTML and JavaScript, but rather between presentation logic and application logic, regardless of the languages used on either side. Focusing on this prevents us from mixing presentational JavaScript with business logic, thus enforcing the separation of concerns, reducing coupling, and improving maintainability.Using JSX With React
Let’s start with the basics. As mentioned before, JSX needs to be transpiled into regular JavaScript before it can be rendered in the browser. Therefore, if you wish to follow along with the examples, you should have a React app already set up. The following examples all come with runnable CodePen demos, so if all you want is to have a quick play around with the code, this might be a good option for you. Otherwise, you could opt for Facebook’s Create React App tool. To use this, you’ll need to have Node and npm installed. If you haven’t, head to the Node.js download page and grab the latest version for your system (npm comes bundled with Node). Alternatively, you can consult our tutorial on installing Node using a version manager. With Node installed, you can create a new React app like so:npx create-react-app myapp
This will create a myapp
folder. Change into this folder and start the development server like so:
cd myapp
npm start
Your default browser will open and you’ll see your new React app. For the purposes of this tutorial, you can work in the App
component, which is located at src/App.js
.
Now let’s get into some code.
Basic Expressions
JSX is extremely similar to plain HTML and uses the same XML-based syntax. Here’s the canonical “Hello, World” example to start with:const element = <h1>Hello, World!</h1>;
ReactDOM.render(element, document.getElementById('root'));
See the Pen jsx-hello-world by SitePoint (@SitePoint) on CodePen.
Note how the<h1>
element is used directly inside regular JavaScript. There are no quotes around it, since it’s not a string, but a language expression.
Similarly, you can use JavaScript in JSX tags by surrounding them with curly brackets:
function getGreeting(name) {
return `Hello, ${name}`;
}
const element = <h1>{getGreeting('John')}</h1>;
ReactDOM.render(element, document.getElementById('root'));
See the Pen jsx-hello-world-with-js by SitePoint (@SitePoint) on CodePen.
You can also use JavaScript expressions when specifying attribute values, such as passing an object containing inline styles in this example. This is useful when you want to pass a dynamic attribute value:const styles = {
color: 'red',
fontStyle: 'italic'
}
const element = <h1 style={styles}>Hello, World!</h1>;
ReactDOM.render(element, document.getElementById('root'));
See the Pen jsx-hello-world-styled by SitePoint (@SitePoint) on CodePen.
Note: if you need to pass a dynamic list of attributes, you can use the spread operator:<h1 {...attributes}></h1>
.
Of course, as with regular HTML, JSX elements can contain children. Those can be string literals, other elements, or JavaScript expressions:
function getGreeting() {
return (
<h2>Welcome to the website</h2>
)
}
const element = <div>
<h1>Hello!</h1>
{getGreeting()}
</div>;
ReactDOM.render(element, document.getElementById('root'));
See the Pen jsx-children by SitePoint (@SitePoint) on CodePen.
Conditional Statements
The fact that you can embed JavaScript expressions and pass around JSX elements opens up many possibilities for structuring your code. A frequent use case is conditionally displaying an element to a logged-in user — such as a personalized message — or a validation error. JSX does not support standardif
statements, but you can use the ternary operator:
const loggedIn = true;
const element = <div>
<h1>Hello!</h1>
<h2>
{(loggedIn) ? 'Welcome back' : 'Nice to meet you'}
</h2>
</div>;
ReactDOM.render(element, document.getElementById('root'));
See the Pen jsx-conditional-example by SitePoint (@SitePoint) on CodePen.
An expression can returnfalse
, true
, null
or undefined
to avoid rendering an element. Returning some falsy values, such as 0
or an empty string, will still render the element:
const error = true;
const element = <div>
<label>
Name:
<input />
{error ? <div style={{color: 'red'}}>Name invalid</div> : null}
</label>
</div>;
ReactDOM.render(element, document.getElementById('root'));
See the Pen jsx-conditional-display by SitePoint (@SitePoint) on CodePen.
Note the double curly braces used in thestyle
attribute. This the syntax for passing an inline object as the value: the outer pair denotes the expression and the inner one is the object itself.
In the above snippet, we see this:
{error ? <div style={{color: 'red'}}>Name invalid</div> : null}
This can be shortened even further, to this:
{error && <div style={{color: 'red'}}>Name invalid</div>}
This works because in JavaScript, true && expression
always evaluates to expression
, and false && expression
always evaluates to false
.
But although this pattern is fairly common, don’t forget about readability. Stick to code conventions that are agreed upon and understood by your team. Also, don’t overdo it with the nesting of conditional constructs. Often people put one ternary operator into another to save a couple of lines of code at the expense of readability. Refactor such code by extracting blocks into separate variables or functions.
Loops
Another frequent use case is to render a list of repeating elements. With JSX, you can’t usefor
loops, but you can iterate over an array using the array map() method. For example, here’s a simple way to render a list of items:
const items = [
'Bread',
'Milk',
'Eggs'
]
const element = <div>
Grocery list:
<ul>
{items.map(item => <li>{item}</li>)}
</ul>
</div>;
ReactDOM.render(element, document.getElementById('root'));
See the Pen jsx-map by SitePoint (@SitePoint) on CodePen.
Obviously, you can use other array methods in the code as well, and it might be tempting to slip in some filtering logic or other calculations. Don’t give in to this! Remember the separation of concerns principle and separate this logic from the rendering code. This will make your code easier to read, understand, and test.Custom Components
The two upcoming sections are more specific to React, but it’s still worth talking through them to get a good understanding of how everything fits together. The prior code examples are extremely simplistic, since they only render a small set of standard HTML elements. In reality, your application will consist of custom components that will contain your application-specific view and logic. React allows you to define custom components and use them in markup as regular HTML elements. A custom element can be defined either as a function or an ES6 class. Note: by React’s naming conventions, custom elements need to start with a capital letter, to distinguish them from standard elements.function FunctionComponent() {
return <h2>This is a function component.</h2>
}
class ClassComponent extends React.Component {
render() {
return <h2>This is a class component.</h2>
}
}
const element = <div>
<FunctionComponent />
<ClassComponent />
</div>;
ReactDOM.render(element, document.getElementById('root'));
See the Pen jsx-custom-components by SitePoint (@SitePoint) on CodePen.
Event Handling
JSX provides a way to bind events similar to regular HTML. You can define a property on an element (the same property names as for regular HTML but camelCased) and pass a function as a value. In React, the callback function will receive a SyntheticEvent object as a first parameter, which is an abstraction on top of the regular browser event object:function handleEvent(e) {
alert('Button clicked!');
console.log(e);
}
const element = <button onClick={handleEvent}>Test click</button>;
ReactDOM.render(element, document.getElementById('root'));
See the Pen jsx-events by SitePoint (@SitePoint) on CodePen.
Note: pay attention to the value ofthis
when passing around event handlers. When you define your component as an ES6 class, you usually define event handlers as methods of the class. Methods passed by value are not bound to a specific this
value, so to keep the current context, you need to explicitly bind them. See React’s documentation for more details on how to do this.
Not Just for React
JSX with React is pretty great stuff. But what if you’re using another framework or library, but still want to use it? Well, you’re in luck — because JSX technically isn’t tied to React. It’s still just DSL or “syntax sugar”, remember? Here are some other projects that use JSX:- You can use JSX in Vue’s
render
function with the help of the @vue/babel-preset-jsx Babel preset. - Some other frameworks that position themselves as minimalist React-compatible alternatives such as Preact, Inferno or Hyperapp use JSX for their rendering layer.
- MDX allows you to use JSX in Markdown files to add interactive JS elements.
Frequently Asked Questions about JSX
What is the difference between JSX and HTML?
JSX, or JavaScript XML, is a syntax extension for JavaScript that allows you to write HTML-like code in your JavaScript files. While it looks similar to HTML, there are some key differences. For instance, JSX is not a string, but an object. This means that you can embed any JavaScript expression within JSX by wrapping it in curly braces. Additionally, JSX is more powerful than HTML as it allows for the use of JavaScript logic, such as loops and conditionals, directly within the markup.
Why should I use JSX in my React project?
JSX makes your React code more readable and easier to write. It allows you to write HTML-like syntax directly in your JavaScript, which means you can create and use HTML elements using JavaScript. This makes it easier to visualize the structure of your UI, especially when dealing with complex components. Additionally, JSX performs optimization while compiling to JavaScript, making your code more efficient.
How do I embed JavaScript expressions in JSX?
You can embed JavaScript expressions in JSX by wrapping them in curly braces. For example, you can include variables, perform calculations, or call functions directly within your JSX code. This makes JSX incredibly powerful, as you can dynamically generate content based on your application’s state or props.
How do I write comments in JSX?
Writing comments in JSX is slightly different than in regular JavaScript. You need to wrap your comments in curly braces, and then use the traditional JavaScript comment syntax. For example, {/* This is a comment */}. This is because JSX is just syntactic sugar for JavaScript, and needs to be compiled down to regular JavaScript.
Can I use JSX with other JavaScript libraries or frameworks?
While JSX is most commonly associated with React, it can be used with any JavaScript library or framework. It’s just a syntax extension for JavaScript, and can be compiled down to regular JavaScript using tools like Babel. This means you can use JSX with libraries like Vue or Angular, or even with vanilla JavaScript.
How do I use JSX to create React components?
You can use JSX to define the render method of your React components. This method should return a JSX expression, which describes what the UI should look like. You can then use this component just like any other HTML element in your JSX code.
What are the naming conventions for JSX elements?
In JSX, user-defined components must start with a capital letter. This is because components that start with a lowercase letter are treated as HTML elements. For example,
How do I handle events in JSX?
In JSX, you can handle events such as onClick or onChange by passing a function as a prop. This function will be called whenever the event occurs. Note that the event names are written in camelCase, rather than lowercase as in HTML.
Can I use JSX without React?
Yes, you can use JSX without React. While JSX is most commonly used with React, it’s just a syntax extension for JavaScript and can be used with any JavaScript library or framework. You just need a compiler like Babel to compile your JSX code into regular JavaScript.
What are the limitations of JSX?
While JSX is incredibly powerful, it does have some limitations. For example, because it’s just syntactic sugar for JavaScript, it can’t be used in a regular HTML file. Additionally, some HTML attributes, like class and for, are reserved words in JavaScript and have to be replaced with className and htmlFor in JSX.
Matt is a professional software developer and is passionate about web dev. Find out more about him at mawburn.com.
Pavels is a software developer from Riga, Latvia, with a keen interest for everything web-related. His interests range from back-end to front-end development, as well as analysis and automation. If you have something to discuss, you can always reach him via Facebook or LinkedIn.