---
source_hash: "09631812"
title: "Chapter 2: JSX"
weight: 370
---

# Chapter 2: JSX

## What is JSX?

JSX (JavaScript XML) is a syntax extension that allows you to write HTML in JavaScript:

```javascript
const element = <h1>Hello World!</h1>;
```

This is **not** HTML. It's JavaScript that will be transformed into React function calls.

```javascript
// This JSX:
const element = <h1 className="title">Hello</h1>;

// Is transformed to:
const element = React.createElement('h1', { className: 'title' }, 'Hello');
```

You don't need to write `React.createElement` - the compiler (Babel/Vite) does it for you.

## Differences with HTML

### className instead of class

`class` is a reserved word in JavaScript:

```javascript
// HTML
<div class="container">

// JSX
<div className="container">
```

### htmlFor instead of for

```javascript
// HTML
<label for="email">

// JSX
<label htmlFor="email">
```

### Style as object

```javascript
// HTML
<div style="color: red; font-size: 16px;">

// JSX - object with camelCase
<div style={{ color: 'red', fontSize: '16px' }}>

// Or with a variable
const styles = { color: 'red', fontSize: '16px' };
<div style={styles}>
```

### camelCase Attributes

```javascript
// HTML
<button onclick="handleClick()">
<input tabindex="1">

// JSX
<button onClick={handleClick}>
<input tabIndex={1}>
```

### Required Tag Closing

```javascript
// HTML
<img src="photo.jpg">
<input type="text">
<br>

// JSX - always close
<img src="photo.jpg" />
<input type="text" />
<br />
```

## JavaScript Expressions in JSX

Use braces `{}` to insert JavaScript:

### Variables

```javascript
const name = "Jean";
const age = 30;

return (
    <div>
        <p>Name: {name}</p>
        <p>Age: {age}</p>
        <p>Birth year: {2024 - age}</p>
    </div>
);
```

### Functions

```javascript
function formatName(user) {
    return `${user.firstName} ${user.lastName}`;
}

const user = { firstName: 'Jean', lastName: 'Dupont' };

return <h1>Hello, {formatName(user)}!</h1>;
```

### Expressions, not statements

In braces, you can use **expressions** (which return a value), not **statements** (if, for, while).

```javascript
// CORRECT - expressions
{name}
{2 + 2}
{formatName(user)}
{isAdmin ? 'Admin' : 'User'}
{items.length}

// INCORRECT - statements
{if (isAdmin) { return 'Admin' }}  // Error!
{for (let i = 0; i < 10; i++) {}}  // Error!
```

## Conditions

### Ternary Operator

To display one thing or another:

```javascript
function Greeting({ isLoggedIn }) {
    return (
        <div>
            {isLoggedIn ? (
                <p>Welcome!</p>
            ) : (
                <p>Please log in</p>
            )}
        </div>
    );
}
```

### && Operator

To display something or nothing:

```javascript
function Notification({ count }) {
    return (
        <div>
            {count > 0 && (
                <span className="badge">{count}</span>
            )}
        </div>
    );
}
```

**Warning**: `{count && <span>...</span>}` will display `0` if count is 0, because 0 is a "falsy" but displayable value. Prefer `{count > 0 && ...}`.

### Variables for Complex Cases

```javascript
function UserStatus({ user }) {
    let statusMessage;

    if (user.isAdmin) {
        statusMessage = <span className="admin">Admin</span>;
    } else if (user.isPremium) {
        statusMessage = <span className="premium">Premium</span>;
    } else {
        statusMessage = <span>Standard</span>;
    }

    return <div>{statusMessage}</div>;
}
```

## Loops with map()

To display a list, use `map()`:

```javascript
function UserList({ users }) {
    return (
        <ul>
            {users.map(user => (
                <li key={user.id}>
                    {user.name}
                </li>
            ))}
        </ul>
    );
}
```

### The key Attribute

**Required** for lists. Allows React to identify each element:

```javascript
// CORRECT - unique ID
{users.map(user => (
    <li key={user.id}>{user.name}</li>
))}

// ACCEPTABLE - if no ID, use index (less performant)
{items.map((item, index) => (
    <li key={index}>{item}</li>
))}

// INCORRECT - no key
{users.map(user => (
    <li>{user.name}</li>  // React warning!
))}
```

### Comparison with PHP

```php
// PHP
<?php foreach ($users as $user): ?>
    <li><?= $user['name'] ?></li>
<?php endforeach; ?>
```

```javascript
// React
{users.map(user => (
    <li key={user.id}>{user.name}</li>
))}
```

## Fragments

A component must return **a single root element**. If you don't want to add an unnecessary `<div>`, use a Fragment:

```javascript
// INCORRECT - multiple root elements
function UserInfo({ user }) {
    return (
        <h1>{user.name}</h1>
        <p>{user.email}</p>  // Error!
    );
}

// CORRECT - with Fragment
function UserInfo({ user }) {
    return (
        <>
            <h1>{user.name}</h1>
            <p>{user.email}</p>
        </>
    );
}

// Or long syntax
import { Fragment } from 'react';

function UserInfo({ user }) {
    return (
        <Fragment>
            <h1>{user.name}</h1>
            <p>{user.email}</p>
        </Fragment>
    );
}
```

## Exercises

### Exercise 1: Convert to JSX

Convert this HTML to JSX:

```html
<div class="card">
    <img src="photo.jpg" alt="Photo">
    <label for="name">Name:</label>
    <input type="text" id="name" tabindex="1">
    <button onclick="save()">Save</button>
</div>
```

**Solution:**

```javascript
<div className="card">
    <img src="photo.jpg" alt="Photo" />
    <label htmlFor="name">Name:</label>
    <input type="text" id="name" tabIndex={1} />
    <button onClick={save}>Save</button>
</div>
```

### Exercise 2: Conditional Rendering

Create a component that displays:

- "Loading..." if `loading` is true
- "No results" if `items` is empty
- The list of items otherwise

**Solution:**

```javascript
function ItemList({ loading, items }) {
    if (loading) {
        return <p>Loading...</p>;
    }

    if (items.length === 0) {
        return <p>No results</p>;
    }

    return (
        <ul>
            {items.map(item => (
                <li key={item.id}>{item.name}</li>
            ))}
        </ul>
    );
}
```

## Key Points to Remember

1. **JSX is not HTML**: it's JavaScript transformed
2. **className** instead of class, **htmlFor** instead of for
3. **Braces `{}`** to insert JavaScript
4. **Ternary `? :`** or **&&** for conditions
5. **map()** for loops, with a **unique key**
6. **Fragments `<></>`** to return multiple elements

[<- Previous Chapter](/training/module2-introduction-react/philosophie) | [Back to Module](/training/module2-introduction-react) | [Next Chapter: Components ->](/training/module2-introduction-react/composants)
