← Back

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

  1. What JSX is and how it works.
  2. How JSX differs from HTML.
  3. Why JSX elements must be closed.
  4. How to use className and htmlFor.
  5. Why JSX requires one parent element.
  6. How React Fragments work.
  7. How to display JavaScript variables and expressions.
  8. How to use dynamic JSX attributes.
  9. How to write conditional expressions in JSX.
  10. 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

Pizza Menu

JSX describes this pizza menu card.

The JSX returned by 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

Pizza Menu

Two pizzas are available.

The wrapper is structural; the heading and paragraph are the visible 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

Welcome, Nikita!

React evaluates {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

Margherita pizza

Size: Large

Two JavaScript strings are inserted into one JSX block.

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

Margherita

Price per pizza: 8.50 €

Quantity: 3

Line total: 25.50 €

The multiplication runs as JavaScript; the browser displays the result: 25.50 €.

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

Pepperoni pizza

Currently unavailable

The false branch of the ternary expression is rendered.

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

Order Total

Subtotal: 25 €

Delivery: 3 €

Total: 28 €

JSX displays the calculated delivery fee and order total.

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 className instead of class, and htmlFor instead of for.
  • 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, and alt.
  • Ternary expressions can select which content React renders.
  • Use the .tsx extension 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.

← Back↑ Back to the top