React.js + Next.js · Module 2. React Basics · Lesson 3
JSX: Describing the User Interface
JSX (JavaScript XML) is a special syntax used in React that allows developers to write HTML-like markup directly inside JavaScript or TypeScript files.
JSX makes it easier to describe what a user interface should look like.
Instead of manually creating and updating HTML elements with JavaScript, we describe the interface using JSX, and React handles the rendering.
JSX looks similar to HTML, but it has its own rules.
Project direction: every example in this lesson describes part of the Pizza Palace menu, cart, or checkout interface.
You will learn
- What JSX is and how it works.
- How JSX differs from HTML.
- Why JSX elements must be closed.
- How to use
classNameandhtmlFor. - Why JSX requires one parent element.
- How React Fragments work.
- How to display JavaScript variables and expressions.
- How to use dynamic JSX attributes.
- How to write conditional expressions in JSX.
- Common JSX mistakes and how to avoid them.
REACT · 01
1. What Is JSX?
JSX is a syntax extension for JavaScript.
It allows developers to write markup that resembles HTML directly inside React components.
Example — A Simple JSX Component
function App() {
return (
<div>
<h1>Pizza Menu</h1>
<p>JSX describes this pizza menu card.</p>
</div>
);
}
export default App;
How It Works
function App() declares a React component.
return specifies the interface that the component should produce.
<div> is the parent element.
<h1> displays a heading.
<p> displays a paragraph.
export default App allows the component to be imported into another file.
Browser Result
App becomes visible interface content.Important: JSX is not HTML. It is transformed into JavaScript that creates React elements.
In TypeScript projects, files containing JSX use the .tsx extension.
REACT · 02
2. JSX vs Traditional HTML
JSX resembles HTML, but some rules are different.
Traditional HTML
<div class="pizza-card">
<h2>Margherita pizza</h2>
<img src="margherita-pizza.jpg" alt="Margherita pizza">
</div>
React JSX
function PizzaCard() {
return (
<div className="pizza-card">
<h2>Margherita pizza</h2>
<img src="margherita-pizza.jpg" alt="Margherita pizza" />
</div>
);
}
Main Differences
| HTML | JSX |
|---|---|
class |
className |
for |
htmlFor |
<img> |
<img /> |
<input> |
<input /> |
| Static markup | Supports JavaScript expressions using {} |
JSX also uses JavaScript-style property names for many DOM attributes.
REACT · 03
3. All JSX Tags Must Be Closed
In HTML, some elements do not require explicit closing tags.
For example:
<img src="margherita-pizza.jpg" alt="Margherita pizza">
<input type="text" name="reference">
In JSX, every element must be closed.
Correct JSX
function App() {
return (
<div>
<img src="margherita-pizza.jpg" alt="Margherita pizza" />
<input type="text" name="reference" />
</div>
);
}
Notice the ending:
/>
This is called a self-closing tag.
It is commonly used for elements that do not contain children.
Incorrect JSX
<img src="margherita-pizza.jpg" alt="Margherita pizza">
Correct JSX
<img src="margherita-pizza.jpg" alt="Margherita pizza" />
Remember: All JSX elements must have a closing tag or use the self-closing syntax.
REACT · 04
4. JSX Attributes — className and htmlFor
Some HTML attributes have different names in JSX.
className
In HTML:
<div class="pizza-card">
In JSX:
<div className="pizza-card">
We use className because JSX DOM properties follow React's attribute naming conventions.
Practical Example — Pizza Card
function PizzaCard() {
return (
<div className="pizza-card">
<h2>Pepperoni pizza</h2>
<p>Price: 10.50 €</p>
</div>
);
}
export default PizzaCard;
CSS:
.pizza-card {
padding: 20px;
background-color: lightgray;
border-radius: 8px;
}
The CSS class styles the pizza card.
htmlFor
In HTML, a label can be connected to an input using for.
In JSX, we use htmlFor.
function DeliveryForm() {
return (
<div>
<label htmlFor="delivery-address">
Delivery address
</label>
<input id="delivery-address" type="text" />
</div>
);
}
Explanation
htmlFor="delivery-address" connects the label to the input with id="delivery-address".
Clicking the label can focus the associated input.
REACT · 05
5. JSX Requires One Parent Element
A React component must return one JSX value.
This means that multiple elements cannot be returned next to each other without a common wrapper.
Incorrect Example
function App() {
return (
<h1>Pizza Menu</h1>
<p>Two pizzas are available.</p>
);
}
This produces a JSX syntax error.
Correct Example — Using div
function App() {
return (
<div>
<h1>Pizza Menu</h1>
<p>Two pizzas are available.</p>
</div>
);
}
Both elements are now inside one parent element.
Browser Result
The parent does not have to be a <div>. It can be another appropriate element or a React Fragment.
REACT · 06
6. React Fragments
Sometimes we need to group JSX elements without adding an extra HTML element to the DOM.
React provides Fragments for this purpose.
Example
function App() {
return (
<>
<h1>Pizza Menu</h1>
<p>Two pizzas are available.</p>
</>
);
}
export default App;
The syntax:
<>
...
</>
is a shorthand for a React Fragment.
Why Use Fragments?
A <div> creates an additional DOM element.
A Fragment groups JSX elements without creating an additional wrapper element in the DOM.
Equivalent Explicit Syntax
import { Fragment } from "react";
function App() {
return (
<Fragment>
<h1>Pizza Menu</h1>
<p>Two pizzas are available.</p>
</Fragment>
);
}
Both versions work.
Important: If a Fragment needs a key, use the explicit <Fragment key={...}> syntax.
REACT · 07
7. JavaScript Variables in JSX
One of the most useful features of JSX is the ability to display JavaScript values.
We use curly braces:
{}
Example — Displaying a Name
const customerName = "Nikita";
function App() {
return (
<div>
<h1>Welcome, {customerName}!</h1>
</div>
);
}
export default App;
Browser Result
{customerName} before rendering the heading.Explanation
customerName is a JavaScript variable.
{customerName} tells JSX to evaluate the variable and display its value.
Without curly braces:
<h1>Welcome, customerName!</h1>
React displays the literal word customerName.
With curly braces:
<h1>Welcome, {customerName}!</h1>
React displays the variable's value.
REACT · 08
8. Using Multiple Variables
Let's create a simple pizza selection.
const pizzaName = "Margherita pizza";
const size = "Large";
function App() {
return (
<div>
<h2>{pizzaName}</h2>
<p>Size: {size}</p>
</div>
);
}
export default App;
Browser Result
Explanation
{pizzaName} displays the pizza name.
{size} displays the selected pizza size.
React can insert JavaScript values directly into JSX.
REACT · 09
9. JavaScript Expressions in JSX
JSX can display not only variables but also JavaScript expressions.
An expression is code that produces a value.
For example:
10 + 5
produces:
15
Practical Example — Pizza Line Total
const pizzaName = "Margherita";
const pizzaPrice = 8.5;
const quantity = 3;
function App() {
return (
<div>
<h2>{pizzaName}</h2>
<p>Price per pizza: {pizzaPrice} €</p>
<p>Quantity: {quantity}</p>
<p>Line total: {pizzaPrice * quantity} €</p>
</div>
);
}
export default App;
Browser Result
Explanation
The expression:
{pizzaPrice * quantity}
calculates the line total.
React displays the result.
Common Mistake
Incorrect:
{pizzaPrice * {quantity}}
Correct:
{pizzaPrice * quantity}
Only one pair of curly braces is needed around the JavaScript expression.
REACT · 10
10. Dynamic JSX Attributes
JavaScript variables can also be used as attribute values.
Static Attribute
<a href="https://react.dev/">
React Documentation
</a>
Dynamic Attribute
const website = "https://react.dev/";
function App() {
return (
<div>
<h1>Learning React</h1>
<a href={website}>
React Documentation
</a>
</div>
);
}
export default App;
Explanation
website contains the URL.
href={website} inserts the value of the variable into the attribute.
Important Rule
For a fixed string:
alt="Margherita pizza"
For a JavaScript variable:
alt={pizzaName}
For a number:
width={320}
Curly braces allow JSX to evaluate JavaScript expressions.
REACT · 11
11. Dynamic Images in JSX
Images can also use JavaScript variables.
Example
const imageUrl = "/images/margherita-pizza.jpg";
const pizzaName = "Margherita pizza";
function App() {
return (
<div>
<h2>{pizzaName}</h2>
<img
src={imageUrl}
alt={pizzaName}
width={320}
/>
</div>
);
}
export default App;
Explanation
src={imageUrl} provides the image location.
alt={pizzaName} provides alternative text.
width={320} sets the image's width attribute.
In a Vite project, an image stored at:
public/images/margherita-pizza.jpg
can be referenced using:
src="/images/margherita-pizza.jpg"
REACT · 12
12. Conditional Expressions in JSX
JSX supports conditional rendering.
This allows us to display different content depending on a condition.
One common approach is the ternary operator:
condition ? valueIfTrue : valueIfFalse
Example — Pizza Availability
const isAvailable = false;
function App() {
return (
<div>
<h2>Pepperoni pizza</h2>
<p>
{isAvailable ? "Available to order" : "Currently unavailable"}
</p>
</div>
);
}
export default App;
Browser Result
Explanation
isAvailable checks whether the pizza is available to order.
If the condition is true, React displays "Available to order".
Otherwise, it displays "Currently unavailable".
Another Example
const isDeliveryAvailable = true;
function App() {
return (
<div>
<h1>Delivery status</h1>
<p>
{isDeliveryAvailable ? "Delivery available" : "Pickup only"}
</p>
</div>
);
}
This technique is called conditional rendering and will be covered in more detail later.
REACT · 13
13. Practical Example — Calculating an Order Total
JSX can display calculated values.
Suppose the cart subtotal is 25 €.
The delivery fee is 3 €.
const subtotal = 25;
const deliveryFee = 3;
function App() {
return (
<div>
<h2>Order Total</h2>
<p>Subtotal: {subtotal} €</p>
<p>Delivery: {deliveryFee} €</p>
<p>Total: {subtotal + deliveryFee} €</p>
</div>
);
}
export default App;
Browser Result
Explanation
The expression:
deliveryFee
provides the delivery charge.
The expression:
subtotal + deliveryFee
calculates the final order total.
For production applications, monetary calculations require appropriate rounding and numerical precision handling.
REACT · 14
14. JSX and TypeScript
When JSX is used inside TypeScript files, the file extension is .tsx.
For example:
App.tsx
PizzaCard.tsx
Header.tsx
TypeScript allows developers to define types for variables and component data.
Example
const pizzaName: string = "Pepperoni pizza";
const quantity: number = 3;
function App() {
return (
<div>
<h2>{pizzaName}</h2>
<p>Quantity: {quantity}</p>
</div>
);
}
export default App;
Explanation
string means text.
number means a number.
TypeScript checks that the values match their declared types.
REACT · 15
15. How JSX Is Rendered in React
In a Vite React application, the entry file is usually:
src/main.tsx
A typical configuration looks like this:
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.tsx";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>
);
Explanation
document.getElementById("root") finds the root HTML element.
createRoot() creates a React root.
.render() renders the App component.
StrictMode enables additional development checks.
The HTML document contains:
<div id="root"></div>
React renders the application inside this element.
Important Note
You normally write your components inside App.tsx and other component files.
You do not need to modify main.tsx for every new JSX exercise.
REACT · 16
16. Common JSX Mistakes
Mistake 1 — Forgetting Curly Braces
Incorrect:
<h1>Hello customerName!</h1>
Correct:
<h1>Hello {customerName}!</h1>
Mistake 2 — Using Two Pairs of Curly Braces for an Expression
Incorrect:
<p>{pizzaPrice * {quantity}}</p>
Correct:
<p>{pizzaPrice * quantity}</p>
Mistake 3 — Forgetting to Close Tags
Incorrect:
<img src="margherita-pizza.jpg" alt="Margherita pizza">
Correct:
<img src="margherita-pizza.jpg" alt="Margherita pizza" />
Mistake 4 — Multiple Root Elements
Incorrect:
return (
<h1>Pizza Menu</h1>
<p>Two pizzas are available.</p>
);
Correct:
return (
<>
<h1>Pizza Menu</h1>
<p>Two pizzas are available.</p>
</>
);
Mistake 5 — Using class Instead of className
Incorrect:
<div class="pizza-card">
Correct:
<div className="pizza-card">
Mistake 6 — Incorrect Conditional Syntax
Incorrect:
<p>{{isAvailable ? "Available to order" : "Currently unavailable"}</p>
Correct:
<p>{isAvailable ? "Available to order" : "Currently unavailable"}</p>
REACT · 17
17. Practice Exercises
Exercise 1 — Display a Variable
Create a variable called customerName and display:
Welcome, Nikita!
Use JSX expressions.
Exercise 2 — Pizza Information
Create two variables:
const pizzaName = "Margherita pizza";
const size = "Large";
Display the pizza name and selected size using JSX.
Exercise 3 — Pizza Line Total
Create:
const pizzaPrice = 8.5;
const quantity = 3;
Calculate and display the line total inside JSX.
Exercise 4 — Dynamic Link
Create:
const website = "https://react.dev/";
Use it as the href value of a link.
Exercise 5 — Pizza Availability
Create:
const isAvailable = false;
Display "Available to order" when the value is true; otherwise display "Currently unavailable".
REACT · 18
18. Key Takeaways
- JSX is a syntax extension for JavaScript.
- JSX allows us to describe React interfaces using HTML-like markup.
- JSX is not HTML.
- Every JSX element must be closed.
- Use
classNameinstead ofclass, andhtmlForinstead offor. - A component must return one parent JSX value; Fragments can group elements without extra DOM markup.
- Curly braces insert JavaScript variables and expressions into JSX.
- Variables can provide dynamic attribute values such as
href,src, andalt. - Ternary expressions can select which content React renders.
- Use the
.tsxextension when JSX and TypeScript appear in the same file.
REACT · 19
19. Further Reading
Next, continue with React components and learn how to split an interface into reusable pieces.