Introduction to JSX
JSX (JavaScript XML) is a syntax extension for JavaScript that makes it easier to write and visualize React elements.
const link = <a href="//react.dev">React</a>;
JSX is not a string, not a template literal, and not HTML.
It compiles to JavaScript objects via tools like Babel.
It is purely for developer experience—not performance.
JSX is syntactic sugar for React.createElement()
and:
Is easier to read and write
Provides better error messages
Is faster to type
Reduces syntax errors
JSX vs. React.createElement()
Without JSX:
const element = React.createElement(
'main',
null,
React.createElement(Title, null, 'Welcome'),
React.createElement(Carousel, { images: 6 }),
React.createElement('a', { href: '/blog' }, 'Go to the blog')
);
With JSX:
const element = (
<main>
<Title>Welcome</Title>
<Carousel images={6} />
<a href="/blog">Go to the blog</a>
</main>
);
JSX Syntax & Examples
Element Creation
<h1 /> // Same as React.createElement('h1')
React.createElement(
'h1',
null,
'Welcome',
);
<h1>Welcome</h1> // Adds Children
React.createElement(
Title,
null,
'Welcome',
);
<Title>Welcome</Title> // Custom components
React.createElement(
Title,
{ size: 6 }
'Welcome',
);
<Title size="6">
Welcome to <strong>Narnia</strong>
</Title>
JSX in Functional Components
Before (class):
import React, { Component } from 'react';
class App extends Component {
render() {
return <h1>Hello <em>World</em>!</h1>;
}
}
After (functional):
import React from 'react';
function App() {
return <h1>Hello <em>World</em>!</h1>;
}
export default App;
You can store JSX in variables:
const title = <h1>Hello <em>World</em>!</h1>;
return title;
Multiline JSX
Wrap JSX in parentheses when returning multiple lines:
return (
<main>
<h1>Hello world</h1>
</main>
);
Or inline:
return <main><h1>Hello world</h1></main>;
Outputting Variables in JSX
function DateTimeNow() {
const dateTime = new Date().toLocaleString();
return <span>Current date and time is {dateTime}.</span>;
}
You can also use JSX variables:
const now = <date>{new Date().toLocaleTimeString()}</date>;
const message = <p>Today is {now}</p>;
Calling Component Functions
function ButtonList({ disabled }) {
const getButton = (text) => (
<button disabled={disabled}>{text}</button>
);
return (
<aside>
{getButton('Up')}
{getButton('Down')}
</aside>
);
}
You can also use JavaScript expressions inside {}
:
<p>Today is {new Date().toLocaleTimeString()}.</p>
Working with Props
HTML attributes and custom props look the same:
<a href="//react.dev">Let's do React!</a>
// on custom Link component
<Link url="//react.dev" framework="React" />
Passing Props Dynamically
function ProfileLink({ url, label }) {
return (
<a href={url} title={label} target="_blank">Profile</a>
);
}
<ProfileLink url="/users/johnny" label="Profile for Johnny" />
Spread operator for props:
<Post {...post} />
Manual prop passing:
<Post id={post.id} title={post.title} content={post.content} />
Special Prop: children
function Link({ url, children }) {
return (
<p>
<a href={url}>{children}</a>
</p>
);
}
function App() {
return (
<>
<Link url="//react.dev"><strong>React</strong></Link>
<Link url="//vuejs.org">Vue</Link>
<Link url="//angular.io">Angular</Link>
</>
);
}
export default App;
With children
:
<Link url="//react.dev">
<strong>React</strong>
</Link>
With content prop:
<Link url="//react.dev" content={<strong>React</strong>} />
JSX Comments
Outside JSX:
// Standard comment
const title = <h1>Hello</h1>;
Inside JSX:
<div>
{/* JSX comment */}
<p>Content</p>
</div>
Gotchas in JSX
Self-closing tags are required:
<img />
Use
className
instead ofclass
Multi-word props: use camelCase (
onClick
,ariaLabel
)style
prop must be an object:{ color: 'blue' }
Boolean attributes: use
{true}
or simply include the propWhitespace is mostly collapsed
data-*
attributes are supported
Transpiling JSX
JSX must be compiled to standard JavaScript using tools such as:
These tools convert JSX syntax to React.createElement()
calls under the hood.