React.js Fundamentals

JSX Fundamentals

18 min Lesson 3 of 40

What is JSX?

JSX (JavaScript XML) is a syntax extension for JavaScript that lets you write HTML-like code in your JavaScript files. It was created by the React team to make creating React elements more intuitive and readable.

JSX is NOT HTML: Although JSX looks similar to HTML, it's actually JavaScript under the hood. When your code runs, JSX gets transformed into regular JavaScript function calls. Understanding this distinction is crucial for mastering React.

Here's a simple example comparing JSX with plain JavaScript:

// JSX syntax (what you write) const element = <h1 className="greeting">Hello, world!</h1>; // What it compiles to (pure JavaScript) const element = React.createElement( 'h1', { className: 'greeting' }, 'Hello, world!' );

The JSX version is much more readable and looks like the HTML you already know. This is why React developers overwhelmingly prefer JSX over plain JavaScript.

JSX Syntax Rules

JSX has specific rules you must follow. Let's explore each one:

1. All Elements Must Be Closed

In HTML, some tags like <img> and <br> don't require closing tags. In JSX, ALL tags must be closed:

// ❌ Wrong - HTML style <img src="photo.jpg"> <br> <input type="text"> // ✅ Correct - JSX style <img src="photo.jpg" /> <br /> <input type="text" />

2. Use className Instead of class

Since "class" is a reserved keyword in JavaScript, JSX uses className for CSS classes:

// ❌ Wrong <div class="container">Content</div> // ✅ Correct <div className="container">Content</div>

3. Use htmlFor Instead of for

Similarly, "for" is a JavaScript keyword, so use htmlFor in labels:

// ❌ Wrong <label for="username">Username:</label> // ✅ Correct <label htmlFor="username">Username:</label>

4. camelCase for Attributes

JSX uses camelCase naming for attributes that would be hyphenated in HTML:

// HTML attributes → JSX attributes onclick → onClick onchange → onChange tabindex → tabIndex maxlength → maxLength autocomplete → autoComplete

5. Must Return a Single Parent Element

JSX expressions must have exactly one root element. You can't return multiple elements without wrapping them:

// ❌ Wrong - multiple root elements function App() { return ( <h1>Hello</h1> <p>Welcome</p> ); } // ✅ Correct - wrapped in single parent function App() { return ( <div> <h1>Hello</h1> <p>Welcome</p> </div> ); }
React Fragments: If you don't want to add an extra <div> wrapper, use React Fragments: <React.Fragment> or the shorthand <>. We'll cover this later in this lesson!

Embedding JavaScript Expressions

One of JSX's most powerful features is the ability to embed JavaScript expressions using curly braces {}:

function Greeting() { const name = 'Sarah'; const age = 25; return ( <div> <h1>Hello, {name}!</h1> <p>You are {age} years old.</p> <p>Next year you will be {age + 1}.</p> </div> ); }

What Can Go Inside Curly Braces?

  • Variables: {userName}
  • Expressions: {2 + 2}, {price * quantity}
  • Function calls: {formatDate(today)}
  • Ternary operators: {isLoggedIn ? 'Logout' : 'Login'}
  • Array methods: {items.map(item => item.name)}
function ProductCard() { const product = { name: 'Laptop', price: 999, inStock: true }; const tax = 0.1; const totalPrice = product.price + (product.price * tax); return ( <div className="product"> <h2>{product.name}</h2> <p>Price: ${product.price}</p> <p>Total with tax: ${totalPrice.toFixed(2)}</p> <p>Status: {product.inStock ? 'In Stock' : 'Out of Stock'}</p> </div> ); }
What You CANNOT Use in JSX Expressions:
  • Statements (if/else, for loops, while loops)
  • Variable declarations (let, const, var)
  • Function definitions
Use expressions only! For conditional rendering, use ternary operators or logical AND (&&).

JSX Attributes and Props

You can pass attributes to JSX elements just like HTML, but using camelCase and expressions:

function UserProfile() { const imageUrl = 'https://example.com/avatar.jpg'; const altText = 'User Avatar'; const isActive = true; return ( <div> {/* String attributes use quotes */} <h1 title="User Profile">Profile</h1> {/* Expression attributes use curly braces */} <img src={imageUrl} alt={altText} /> {/* Boolean attributes */} <button disabled={!isActive}>Submit</button> {/* Inline styles as objects */} <p style={{ color: 'blue', fontSize: '18px' }}> Welcome back! </p> </div> ); }
Style Attribute Syntax: Notice the double curly braces in the style attribute: style={{ color: 'blue' }}. The outer braces indicate a JavaScript expression, and the inner braces create a JavaScript object. CSS properties use camelCase: fontSize, backgroundColor, etc.

Conditional Rendering

JSX allows you to conditionally render content using several techniques:

1. Ternary Operator (condition ? true : false)

function LoginButton({ isLoggedIn }) { return ( <div> {isLoggedIn ? ( <button>Logout</button> ) : ( <button>Login</button> )} </div> ); }

2. Logical AND Operator (&&)

Use && when you want to render something only if a condition is true:

function Notification({ hasNewMessages, messageCount }) { return ( <div> <h1>Dashboard</h1> {hasNewMessages && ( <div className="alert"> You have {messageCount} new messages! </div> )} </div> ); }
How && Works in JSX: JavaScript evaluates condition && expression. If the condition is true, it returns the expression. If false, it returns false (which React doesn't render). This is a concise way to conditionally show elements.

3. Element Variables

For complex conditions, store JSX in variables:

function Greeting({ user }) { let content; if (user.isAdmin) { content = <h1>Welcome back, Admin {user.name}!</h1>; } else if (user.isVIP) { content = <h1>Welcome, VIP {user.name}!</h1>; } else { content = <h1>Hello, {user.name}!</h1>; } return ( <div> {content} <p>Last login: {user.lastLogin}</p> </div> ); }

Rendering Lists

To render lists in React, use JavaScript's .map() method to transform arrays into JSX elements:

function ShoppingList() { const items = ['Apples', 'Bananas', 'Oranges', 'Milk', 'Bread']; return ( <ul> {items.map((item, index) => ( <li key={index}>{item}</li> ))} </ul> ); }

For objects with unique IDs, use the ID as the key:

function UserList() { const users = [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' }, { id: 3, name: 'Charlie', email: 'charlie@example.com' } ]; return ( <div> {users.map(user => ( <div key={user.id} className="user-card"> <h3>{user.name}</h3> <p>{user.email}</p> </div> ))} </div> ); }
The "key" Prop is Required: When rendering lists, React requires a unique key prop for each element. This helps React identify which items have changed, been added, or removed. Always use stable, unique IDs when available. Avoid using array indices as keys for dynamic lists (it's OK for static lists that never change).

React Fragments

React Fragments let you group multiple elements without adding extra nodes to the DOM:

// Using React.Fragment (long syntax) function Table() { return ( <table> <tbody> <React.Fragment> <tr><td>Row 1</td></tr> <tr><td>Row 2</td></tr> </React.Fragment> </tbody> </table> ); } // Using Fragment shorthand (recommended) function Table() { return ( <table> <tbody> <> <tr><td>Row 1</td></tr> <tr><td>Row 2</td></tr> </> </tbody> </table> ); }
When to Use Fragments: Use fragments when you need to return multiple adjacent elements without wrapping them in a <div>. This is especially useful for maintaining correct HTML structure (like in tables) and avoiding unnecessary DOM nesting.

Fragments can also accept the key attribute when rendering lists (but only with the long syntax):

function Glossary({ items }) { return ( <dl> {items.map(item => ( <React.Fragment key={item.id}> <dt>{item.term}</dt> <dd>{item.definition}</dd> </React.Fragment> ))} </dl> ); }

Comments in JSX

Adding comments in JSX requires special syntax:

function Example() { return ( <div> {/* This is a single-line comment in JSX */} {/* This is a multi-line comment in JSX */} <h1>Hello World</h1> {/* Comments inside attributes work too */} <input type="text" {/* disabled */} placeholder="Enter text" /> </div> ); } // Regular JavaScript comments work outside JSX // This is a regular comment

JSX vs HTML: Key Differences Summary

HTML vs JSX Differences: 1. Class attribute: HTML: class="my-class" JSX: className="my-class" 2. For attribute: HTML: <label for="input"> JSX: <label htmlFor="input"> 3. Self-closing tags: HTML: <img src="photo.jpg"> JSX: <img src="photo.jpg" /> 4. Style attribute: HTML: style="color: red; font-size: 18px" JSX: style={{ color: 'red', fontSize: '18px' }} 5. Event handlers: HTML: onclick="handleClick()" JSX: onClick={handleClick} 6. Boolean attributes: HTML: <input disabled> JSX: <input disabled={true} /> or <input disabled /> 7. Multiple root elements: HTML: Can have multiple JSX: Must have single parent or Fragment
Exercise 1: Basic JSX Practice

Create a component called PersonCard that displays a person's information. Use JSX to render:

  • A heading with the person's full name
  • A paragraph with their age (calculate years until 100)
  • An image with their avatar (use a placeholder URL)
  • A paragraph showing "Active" if they're active, otherwise "Inactive"
  • Apply CSS classes and inline styles

Data to use:

const person = { firstName: 'John', lastName: 'Doe', age: 28, avatar: 'https://via.placeholder.com/150', isActive: true };
Exercise 2: Conditional Rendering

Create a WeatherCard component that displays weather information with conditional rendering:

  • Show a sun icon ☀️ if temperature > 25°C
  • Show a cloud icon ☁️ if temperature is between 15-25°C
  • Show a snowflake ❄️ if temperature < 15°C
  • Display a warning message if temperature > 35°C or < 0°C
  • Show "Bring an umbrella" if isRaining is true

Data to use:

const weather = { temperature: 28, isRaining: false, location: 'New York' };
Exercise 3: Rendering Lists

Create a BookshelfComponent that displays a list of books:

  • Map through the books array to create a card for each book
  • Each card should show: title, author, year, and rating
  • Add a ⭐ star for each point of rating (e.g., 5 stars for rating 5)
  • Apply different background colors based on rating (green > 4, yellow 3-4, red < 3)
  • Use proper keys for list items

Data to use:

const books = [ { id: 1, title: '1984', author: 'George Orwell', year: 1949, rating: 5 }, { id: 2, title: 'To Kill a Mockingbird', author: 'Harper Lee', year: 1960, rating: 5 }, { id: 3, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald', year: 1925, rating: 4 }, { id: 4, title: 'Moby Dick', author: 'Herman Melville', year: 1851, rating: 3 } ];

Summary

In this lesson, you mastered JSX fundamentals:

  • JSX is a syntax extension that looks like HTML but is actually JavaScript
  • All JSX tags must be closed (self-closing for single tags)
  • Use className instead of class, htmlFor instead of for
  • Embed JavaScript expressions in JSX using curly braces {}
  • JSX attributes use camelCase (onClick, onChange, etc.)
  • Conditional rendering uses ternary operators, && operator, or element variables
  • Render lists using .map() with unique key props
  • React Fragments (<></>) group elements without extra DOM nodes
  • Comments in JSX use {/* comment */} syntax

In the next lesson, we'll explore React components in depth, learning how to create reusable, composable pieces of UI with function components!