30. React Module 2: JSX (JavaScript XML)#
30.1. 1. What is JSX?#
JSX stands for JavaScript XML. It’s a syntax extension for JavaScript that allows you to write HTML-like code directly in your JavaScript files.
30.1.1. Key Benefits:#
Makes React code more readable and intuitive
Allows you to write HTML structures in the same file as JavaScript logic
Converts HTML tags into React elements
Provides compile-time error checking
30.1.2. JSX vs. Regular JavaScript#
With JSX (Recommended):
import { createRoot } from 'react-dom/client';
const myElement = <h1>I Love JSX!</h1>;
createRoot(document.getElementById('root')).render(myElement);
// Output: Renders "I Love JSX!" as an h1 element
Without JSX (Verbose):
import React from 'react';
import { createRoot } from 'react-dom/client';
const myElement = React.createElement('h1', {}, 'I do not use JSX!');
createRoot(document.getElementById('root')).render(myElement);
// Output: Renders "I do not use JSX!" as an h1 element
As you can see, JSX makes the code much cleaner and easier to understand!
30.2. 2. Expressions in JSX#
You can embed any JavaScript expression inside JSX by wrapping it in curly braces {}.
30.2.1. Basic Expressions#
const myElement = <h1>React is {5 + 5} times better with JSX</h1>;
// Output: "React is 10 times better with JSX"
30.2.2. Using Variables#
const name = "Alice";
const age = 25;
const greeting = <h1>Hello, {name}! You are {age} years old.</h1>;
// Output: "Hello, Alice! You are 25 years old."
30.2.3. Using Functions#
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'John',
lastName: 'Doe'
};
const element = <h1>Hello, {formatName(user)}!</h1>;
// Output: "Hello, John Doe!"
30.2.4. Using Conditional Expressions#
const isLoggedIn = true;
const message = (
<h1>
{isLoggedIn ? 'Welcome back!' : 'Please sign in.'}
</h1>
);
// Output: "Welcome back!"
30.2.5. Using Array Methods#
const numbers = [1, 2, 3, 4, 5];
const listItems = (
<ul>
{numbers.map(number => <li key={number}>{number * 2}</li>)}
</ul>
);
/* Output:
<ul>
<li>2</li>
<li>4</li>
<li>6</li>
<li>8</li>
<li>10</li>
</ul>
*/
30.3. 3. Multi-line JSX#
When writing JSX that spans multiple lines, wrap it in parentheses () for better readability.
30.3.1. Example: Creating a List#
const myElement = (
<ul>
<li>Apples</li>
<li>Bananas</li>
<li>Cherries</li>
</ul>
);
/* Output:
• Apples
• Bananas
• Cherries
*/
30.3.2. Example: Complex Layout#
const card = (
<div className="card">
<img src="profile.jpg" alt="Profile" />
<h2>John Doe</h2>
<p>Software Developer</p>
<button>Contact</button>
</div>
);
30.4. 4. One Top-Level Element Rule#
JSX expressions must have exactly ONE parent element. You cannot return multiple sibling elements without wrapping them.
30.4.1. ❌ Wrong - Multiple Top-Level Elements#
// This will cause an error!
const myElement = (
<p>I am a paragraph.</p>
<p>I am a paragraph too.</p>
);
30.4.2. ✅ Correct - Wrapped in a <div>#
const myElement = (
<div>
<p>I am a paragraph.</p>
<p>I am a paragraph too.</p>
</div>
);
30.4.3. ✅ Better - Using React Fragments#
React Fragments let you group elements without adding extra DOM nodes. Use <>...</> (shorthand) or <React.Fragment>...</React.Fragment>.
const myElement = (
<>
<p>I am a paragraph.</p>
<p>I am a paragraph too.</p>
</>
);
// Output: Two paragraphs without an extra wrapper div in the DOM
When to use Fragments:
When you don’t want extra wrapper elements in the DOM
When returning multiple elements from a component
When working with CSS Grid or Flexbox layouts where extra divs can break styling
30.5. 5. Elements Must Be Closed#
JSX follows XML rules, so all elements must be properly closed.
30.5.2. Regular Elements#
// ✅ Correct
const paragraph = <p>Hello World</p>;
// ❌ Wrong
const paragraph = <p>Hello World;
30.6. 6. className Instead of class#
Since class is a reserved keyword in JavaScript, JSX uses className instead.
// ✅ Correct - Use className
const myElement = <h1 className="header-title">Hello World</h1>;
// ❌ Wrong - Don't use class
const myElement = <h1 class="header-title">Hello World</h1>;
30.6.1. Multiple Classes#
const myElement = <div className="card primary-card shadow">Content</div>;
// With template literals
const cardType = "primary";
const myElement = <div className={`card ${cardType}-card shadow`}>Content</div>;
30.6.2. Conditional Classes#
const isActive = true;
const myElement = (
<button className={isActive ? 'btn-active' : 'btn-inactive'}>
Click Me
</button>
);
30.7. 7. Other Attribute Differences#
JSX uses camelCase for HTML attributes that have hyphens:
HTML Attribute |
JSX Attribute |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30.7.1. Example#
const form = (
<div>
<label htmlFor="username">Username:</label>
<input
type="text"
id="username"
maxLength={20}
readOnly={false}
onChange={(e) => console.log(e.target.value)}
/>
</div>
);
30.9. 9. JSX in React Components#
JSX works perfectly inside React components. Components are JavaScript functions that return JSX.
30.9.1. Basic Component#
import { createRoot } from 'react-dom/client';
function Car() {
return (
<>
<h2>My Car</h2>
<p>It is a Ford Mustang.</p>
</>
);
}
createRoot(document.getElementById('root')).render(<Car />);
/* Output:
My Car
It is a Ford Mustang.
*/
30.9.2. Component with Variables#
function Car() {
const brand = "Ford";
const model = "Mustang";
const year = 2024;
return (
<>
<h2>My Car</h2>
<p>It is a {year} {brand} {model}.</p>
</>
);
}
/* Output:
My Car
It is a 2024 Ford Mustang.
*/
30.9.3. Component with Logic#
function Greeting() {
const hour = new Date().getHours();
let message;
if (hour < 12) {
message = "Good morning!";
} else if (hour < 18) {
message = "Good afternoon!";
} else {
message = "Good evening!";
}
return <h1>{message}</h1>;
}
// Output: "Good morning!" (if before noon)
30.9.4. Component with Props#
function UserCard({ name, role, email }) {
return (
<div className="user-card">
<h2>{name}</h2>
<p className="role">{role}</p>
<p className="email">{email}</p>
</div>
);
}
// Usage
<UserCard
name="Alice Johnson"
role="Software Engineer"
email="alice@example.com"
/>
/* Output:
Alice Johnson
Software Engineer
alice@example.com
*/
30.10. 10. Inline Styles in JSX#
Styles in JSX are specified as JavaScript objects with camelCase properties.
const divStyle = {
color: 'blue',
backgroundColor: 'lightgray',
padding: '10px',
borderRadius: '5px'
};
const myElement = <div style={divStyle}>Styled Content</div>;
30.10.1. Inline Style Object#
const myElement = (
<h1 style={{
color: 'red',
fontSize: '24px',
textAlign: 'center'
}}>
Styled Heading
</h1>
);
Note: The double curly braces {{}} are:
Outer
{}: JSX expressionInner
{}: JavaScript object
30.11. 11. Conditional Rendering in JSX#
30.11.1. Using Ternary Operator#
function LoginButton({ isLoggedIn }) {
return (
<button>
{isLoggedIn ? 'Logout' : 'Login'}
</button>
);
}
30.11.2. Using Logical AND (&&)#
function Notification({ hasMessages, messageCount }) {
return (
<div>
<h1>Inbox</h1>
{hasMessages && <p>You have {messageCount} new messages!</p>}
</div>
);
}
// If hasMessages is true: shows the paragraph
// If hasMessages is false: shows nothing
30.11.3. Using If-Else Before Return#
function Dashboard({ user }) {
if (!user) {
return <h1>Please log in</h1>;
}
if (user.role === 'admin') {
return <h1>Admin Dashboard</h1>;
}
return <h1>User Dashboard</h1>;
}
30.12. 12. Lists and Keys#
When rendering lists, each item needs a unique key prop to help React identify which items have changed.
function FruitList() {
const fruits = ['Apple', 'Banana', 'Cherry', 'Date'];
return (
<ul>
{fruits.map((fruit, index) => (
<li key={index}>{fruit}</li>
))}
</ul>
);
}
/* Output:
• Apple
• Banana
• Cherry
• Date
*/
30.12.1. Using Unique IDs as Keys (Best Practice)#
function TodoList() {
const todos = [
{ id: 1, text: 'Learn React', completed: false },
{ id: 2, text: 'Build a project', completed: false },
{ id: 3, text: 'Deploy app', completed: true }
];
return (
<ul>
{todos.map(todo => (
<li key={todo.id} style={{
textDecoration: todo.completed ? 'line-through' : 'none'
}}>
{todo.text}
</li>
))}
</ul>
);
}
/* Output:
• Learn React
• Build a project
• Deploy app (crossed out)
*/
30.13. 🔴 Quiz: React JSX#
Q1: What does JSX stand for? A) JavaScript XML B) JavaScript Extension C) Java Syntax Extension
Q2: How do you embed a JavaScript expression in JSX?
A) [expression]
B) {expression}
C) (expression)
Q3: Which is the correct way to create a self-closing input in JSX?
A) <input type="text">
B) <input type="text" />
C) <input type="text"></input>
Q4: What should you use instead of class in JSX?
A) class
B) className
C) classname
Q5: How do you write comments in JSX?
A) // comment
B) <!-- comment -->
C) {/* comment */}
Q6: What is wrong with this code?
const element = (
<h1>Hello</h1>
<p>World</p>
);
A) Nothing, it’s correct B) Missing parentheses C) Multiple top-level elements without a wrapper
Q7: What is the output of this code?
const x = 10;
const element = <h1>{x > 5 ? 'Big' : 'Small'}</h1>;
A) <h1>Big</h1>
B) <h1>Small</h1>
C) <h1>10</h1>
Q8: Which is the correct way to use a Fragment?
A) <Fragment>...</Fragment>
B) <>...</>
C) Both A and B are correct
Q9: What attribute should you use for a label’s “for” in JSX?
A) for
B) htmlFor
C) labelFor
Q10: Why do we need keys when rendering lists? A) For styling purposes B) To help React identify which items have changed C) To make the code look better
Q11: What is the correct way to apply inline styles in JSX?
A) style="color: red"
B) style={{color: 'red'}}
C) style={color: 'red'}
Q12: What will this render?
const show = false;
const element = <div>{show && <p>Hello</p>}</div>;
A) <div><p>Hello</p></div>
B) <div>false</div>
C) <div></div> (empty div)
See Answers
A1: A. JSX stands for JavaScript XML, allowing you to write HTML-like syntax in JavaScript.
A2: B. Use curly braces {} to embed JavaScript expressions in JSX.
A3: B. Self-closing tags in JSX must end with />.
A4: B. Use className instead of class because class is a reserved keyword in JavaScript.
A5: C. JSX comments use the syntax {/* comment */}.
A6: C. JSX must have one top-level element. Wrap multiple elements in a <div> or Fragment <>.
A7: A. Since 10 > 5 is true, the ternary operator returns 'Big'.
A8: C. Both <React.Fragment> and the shorthand <> are valid Fragment syntax.
A9: B. Use htmlFor instead of for in JSX for label elements.
A10: B. Keys help React identify which items have changed, been added, or removed, improving performance.
A11: B. Inline styles use double curly braces: outer for JSX expression, inner for the style object.
A12: C. When using &&, if the left side is false, nothing is rendered. The div will be empty.
30.8. 8. Comments in JSX#
Comments in JSX are written using
{/* comment */}syntax.Note: Regular JavaScript comments
//or/* */won’t work inside JSX markup.