Skip to main content

JSX

What is JSX​

JSX is an extension for JavaScript used in React. JSX lets you write HTML-like code inside JavaScript. This allows us to describe what a component renders with a structure that is familiar to web developers - HTML. React compiles our JSX into JavaScript calls to create elements and render them on the page.

For example, we created a Greeting component.

Greeting.tsx
function Greeting() {
return (
<h1>Good morning!</h1>
)
}
export default Greeting;

This looks like HTML that is returned by our JavaScript function. However, this is actually JSX. React compiles it into something like:

React.createElement('h1', null, 'Good morning!);
YES!

WooHoo!! We didn't have to write the DOM instructions - React handles that 😊.

Why JSX​

JSX makes your UI:

  • declarative - you describe what you want to render, React handles the DOM
  • components - you build complex UIs from small, reusable components
  • integrated with logic - it's JavaScript, so loops, conditionals, variables, ... all our programmer tools work
JSX

JSX is not HTML, but a JavaScript syntax that looks like HTML β€” designed to describe UI in a familiar, readable way inside React components.

Rules of JSX​

JSX is stricter than HTML. This section contains three important rules to remember when writing JSX. Examples of each are included.

1. Return a single root element​

Components must return a single root element. To return multiple elements from a component, wrap them with a single parent tag. You can add <div> </div> tags, or just <> </>

Here is an example component where we have more than one element to render, a heading and a paragraph. JSX requires that they be wrapped as a single component. We can wrap them in <div> </div> tags:

DoubleGreeting.tsx
const DoubleGreeting = function() {
return (
<div>
<h1>Good morning!</h1>
<p>Glad you are here.</p>
</div>
)
}
export default DoubleGreeting;

Use the DoubleGreeting component like:

 ...
This is my double greeting: <DoubleGreeting />
...

Or, we can wrap them with the shorthand <> </>:

const DoubleGreeting = function() {
return (
<>
<h1>Good morning!</h1>
<p>Glad you are here.</p>
</>
)
}
export default DoubleGreeting;

Use DoubleGreeting as:

 ...
This is my double greeting: <DoubleGreeting />
...

Either syntax will produce:

This is my double greeting:

Good morning!

Glad you are here.

note

Why can components only return a single element? JSX is transformed to JavaScript objects. You can't return two objects from a function without wrapping them into an array. So, you also can't return two JSX tags without wrapping them into another tag.

2. Close all tags​

In HTML, the / is not required to close the <img> tag. However, in JSX, all tags must be closed, either <>... </> or <..../> if a singleton tag.

const Profile = () => (
<img
src="/img/react-buzz-lightyear.png"
alt="Buzz Lightyear"
width="100px"
/>
)
export default Profile;

3. Attributes use camelCase​

In JSX, attributes use camelCase. For example, className in JSX instead of class as in HTML.

We use two attributes in this component that incorporates an event handler.

  • use className instead of class
  • use onClick instead of onclick
AlertThis.tsx
export default function AlertThis() {
const handleClick = () => {
alert('Alert Issued!');
};
return (
<button className="btn" onClick={handleClick}>
ALERT
</button>
);
}

We can use the AlertThis component in a component:

 ...
Click this <AlertThis /> to issue an alert message!
...

... and it is rendered as:

Click this to issue an alert message!

handlers

Note that the event handler is part of the function component and sits at the top of the functional component before the JSX.

JavaScript Expressions in {}​

In JSX, the curly braces are used to embed JavaScript expressions inside your markup. This allows you to embed values, logic, and function calls directly into your HTML-like markup. Curly braces {} tell the transpiler to evaluate what is in the curly braces as JavaScript.

This example renders the current value of a variable:

const name = "Joe";

return <h1>Hello, {name}!</h1>;

{name} evaluates to "Joe", so the return becomes:

<h1>Hello, Joe!</h1>

Expressions vs. statements​

Expressions always produce a value. Examples:

2 + 2         // β†’ 4
user.name // β†’ "Bob"
isLoggedIn ? "Welcome" : "Please sign in" // β†’ "Welcome"

Statements perform an action but do not directly produce a value you can use inline. A statement executes, but it doesn’t itself evaluate to a usable result. Examples:

if (x > 0) { ... }
for (let i = 0; i < 5; i++) { ... }
return value;

JSX allows only expressions in the {}, not full statements.

Conditional expressions​

JavaScript expressions, not statements, are allowed inside the curly braces. That’s why the conditional (ternary) operator is so handyβ€”it gives you a value in-line where a statement like if or if/else cannot. To break a conditional into an allowable expression, the ternary operator provides a solution as in this example:

Welcome.tsx
const Welcome = () => {
const isLoggedIn = true;
return (
<div>
{ isLoggedIn ? ( <p>Welcome!</p> ) : ( <p>Please login!</p> )}
</div>
);
}
export default Welcome;

The conditional statements in the example below are valid because they are just part of the JavaScript function and outside the JSX markup. You can include any valid JavaScript/TypeScript in the function component. However, only JavaScript expressions can be evaluated in the {} of the JSX.

Welcome.tsx
const Welcome = () => {
const isLoggedIn = true;

let message;
if (isLoggedIn) {
message = <p>Welcome!</p>;
} else {
message = <p>Please login!</p>;
}

return (
<div>
{message}
</div>
);
};
export default Welcome;

map to generate list​

For loops are not expressions, so cannot be used within JSX. However, we can use JavaScript map. MDN JS Map Array To map over an array of posts and display the title for each one. The posts are passed as part of the props parameter. See the example below which uses map to generate a new list of titles wrapped in <li> </li> tags.

ListPosts.tsx
const ListPosts = ({ posts }) => {
const postItems = posts.map((post) => (
<li key={post.id}>{post.title}</li>
));

return (
<ul>
{postItems}
</ul>
);
};
export default ListPosts;
Expression TypeExampleResult
Variable{name}"Diane"
Math{2 + 2}4
Ternary condition{isLoggedIn ? 'Welcome' : 'Sign in'}Dynamic text
Function call{getMessage()}Whatever getMessage() returns
Array mapping{items.map(item => <li>{item}</li>)}Renders a list
String concat{first + ' ' + last}Full name string

How JSX Differs from HTML​

Here's a recap of how JSX differs from basic HTML.

FeatureJSX (in React)HTML
Syntax ContextWritten in JavaScript (.jsx, .tsx) filesWritten in .html files
AttributesUses camelCase (className, onClick)Uses HTML names (class, onclick)
JavaScript ExpressionsCan embed JavaScript expressions inside curly braces {}Cannot embed JS
ComponentsSupports custom components like <Greeting />Only standard HTML tags
Self-closing TagsRequired for empty tags (<img />)Optional in HTML (<img>)

Nested Components​

React components can be combined and nested to create complex user interfaces. Below is an example App component that renders multiple child components. To use the <Greeting /> and <Profile /> components we import them:

App.tsx
import Greeting from './Greeting'; // Assuming Greeting.tsx is in the same directory
import Profile from './Profile'; // Assuming Profile.tsx is in the same directory

function App() {
return (
<div className="m-12 flex h-[500px] flex-col items-center justify-center bg-green-400 text-center text-3xl p-12 md:p-14 lg:p-16 xl:p-20">
<DoubleGreeting />
<Profile />
<Profile />
<Profile />
</div>
);
}

Good morning!

Buzz LightyearBuzz LightyearBuzz Lightyear
info

In React, JSX is the syntax used to define the structure of the UI, and it’s what a component returns. Everything else in the component β€” including variables, logic, functions, conditionals, loops, β€” is written using standard JavaScript/TypeScript.

caution

If a component was not the default export, use {} on import.
ie. import { Greeting } from ./Greeting';