React JSX Syntax Guide
Overview
JSX (JavaScript XML) is one of React's core features. It's a syntax extension for JavaScript that allows us to write HTML-like markup within JavaScript code. JSX makes component structure more intuitive and easier to understand.
🎯 What is JSX?
Basic JSX Concept
jsx
// JSX example
const element = <h1>Hello, React!</h1>;
// This is not a string, nor is it HTML
// This is JSX - a syntax extension for JavaScriptThe Nature of JSX
jsx
// JSX code
const element = <h1 className="greeting">Hello, world!</h1>;
// Compiled JavaScript code
const element = React.createElement(
'h1',
{ className: 'greeting' },
'Hello, world!'
);
// Final generated object
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};📝 JSX Basic Syntax
1. Embedding Expressions
Use curly braces {} to embed JavaScript expressions in JSX:
jsx
function Greeting() {
const name = 'John';
const age = 25;
return (
<div>
{/* Embedding variables */}
<h1>Hello, {name}!</h1>
{/* Embedding expressions */}
<p>Next year you'll be {age + 1} years old</p>
{/* Embedding function calls */}
<p>Current time: {new Date().toLocaleTimeString()}</p>
{/* Embedding ternary expressions */}
<p>{age >= 18 ? 'Adult' : 'Minor'}</p>
</div>
);
}2. JSX Attributes
jsx
function ImageCard() {
const imageUrl = 'https://example.com/image.jpg';
const altText = 'Sample image';
const isActive = true;
return (
<div>
{/* String attributes */}
<img src="logo.png" alt="Logo" />
{/* Dynamic attributes */}
<img src={imageUrl} alt={altText} />
{/* Boolean attributes */}
<button disabled={!isActive}>Click</button>
{/* className instead of class */}
<div className="container">Content</div>
{/* camelCase naming */}
<label htmlFor="username">Username</label>
<input id="username" tabIndex="1" />
</div>
);
}3. Children Elements
jsx
function Layout() {
return (
<div className="layout">
{/* Single child element */}
<header>
<h1>Website Title</h1>
</header>
{/* Multiple child elements */}
<main>
<article>Article content</article>
<aside>Sidebar</aside>
</main>
{/* Nested child elements */}
<footer>
<div>
<p>Copyright information</p>
<p>Contact details</p>
</div>
</footer>
</div>
);
}🔧 Advanced JSX Usage
1. Conditional Rendering
jsx
function UserGreeting({ isLoggedIn, username }) {
return (
<div>
{/* Using && operator */}
{isLoggedIn && <p>Welcome back, {username}!</p>}
{/* Using ternary expression */}
{isLoggedIn ? (
<button>Logout</button>
) : (
<button>Login</button>
)}
{/* Using IIFE */}
{(() => {
if (isLoggedIn) {
return <p>Logged in</p>;
} else {
return <p>Not logged in</p>;
}
})()}
</div>
);
}2. List Rendering
jsx
function TodoList() {
const todos = [
{ id: 1, text: 'Learn React', completed: false },
{ id: 2, text: 'Write code', completed: true },
{ id: 3, text: 'Test application', completed: false }
];
return (
<ul>
{todos.map(todo => (
<li
key={todo.id}
style={{
textDecoration: todo.completed ? 'line-through' : 'none'
}}
>
{todo.text}
</li>
))}
</ul>
);
}3. Fragments
jsx
function Table() {
return (
<table>
<tbody>
{/* Using Fragment to avoid extra DOM nodes */}
<React.Fragment>
<tr><td>Row 1</td></tr>
<tr><td>Row 2</td></tr>
</React.Fragment>
{/* Short syntax */}
<>
<tr><td>Row 3</td></tr>
<tr><td>Row 4</td></tr>
</>
</tbody>
</table>
);
}4. Styling
jsx
function StyledComponent() {
// Inline style object
const containerStyle = {
backgroundColor: '#f0f0f0',
padding: '20px',
borderRadius: '8px'
};
const isImportant = true;
return (
<div>
{/* Inline styles */}
<div style={containerStyle}>
<h2 style={{ color: 'blue', fontSize: '24px' }}>Title</h2>
</div>
{/* Dynamic className */}
<p className={`text ${isImportant ? 'important' : ''}`}>
Content
</p>
{/* Using template literals */}
<div className={`card ${isImportant && 'highlight'}`}>
Card content
</div>
</div>
);
}🎨 Special Cases in JSX
1. Comments
jsx
function CommentExample() {
return (
<div>
{/* This is a comment in JSX */}
{/*
Multi-line comment
can be written like this
*/}
<h1>Title</h1>
{
// Single-line comments also work
// but need to be inside curly braces
}
</div>
);
}2. Self-Closing Tags
jsx
function SelfClosingTags() {
return (
<div>
{/* Self-closing tags in HTML must be closed in JSX */}
<img src="image.jpg" alt="Image" />
<input type="text" />
<br />
<hr />
{/* Custom components can also be self-closing */}
<CustomComponent />
</div>
);
}3. Reserved Words
jsx
function ReservedWords() {
return (
<div>
{/* class -> className */}
<div className="container"></div>
{/* for -> htmlFor */}
<label htmlFor="input">Label</label>
<input id="input" />
{/* Other camelCase naming */}
<div tabIndex="0" onClick={() => {}}></div>
</div>
);
}🔒 JSX Security
Preventing XSS Attacks
jsx
function SafeComponent() {
// User input content
const userInput = '<script>alert("XSS")</script>';
return (
<div>
{/* React automatically escapes to prevent XSS */}
<p>{userInput}</p>
{/* Displays as: <script>alert("XSS")</script> */}
{/* If you really need to render HTML (not recommended) */}
<div dangerouslySetInnerHTML={{ __html: userInput }} />
{/* This will execute the script, very dangerous! */}
</div>
);
}📋 JSX Best Practices
1. Keep JSX Clean
jsx
// ❌ Bad practice
function BadExample() {
return (
<div>
{users.filter(u => u.active).map(u => (
<div key={u.id}>
{u.name} - {u.email} - {u.age > 18 ? 'Adult' : 'Minor'}
</div>
))}
</div>
);
}
// ✅ Good practice
function GoodExample() {
const activeUsers = users.filter(u => u.active);
return (
<div>
{activeUsers.map(user => (
<UserCard key={user.id} user={user} />
))}
</div>
);
}
function UserCard({ user }) {
const ageStatus = user.age > 18 ? 'Adult' : 'Minor';
return (
<div>
{user.name} - {user.email} - {ageStatus}
</div>
);
}2. Use Conditional Rendering Wisely
jsx
function ConditionalExample({ isLoading, error, data }) {
// ✅ Early return
if (isLoading) {
return <LoadingSpinner />;
}
if (error) {
return <ErrorMessage error={error} />;
}
if (!data) {
return <EmptyState />;
}
return <DataDisplay data={data} />;
}3. Use Key Attributes
jsx
function ListExample() {
const items = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
];
return (
<ul>
{/* ✅ Use unique id as key */}
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
{/* ❌ Avoid using index as key (unless list is static) */}
{items.map((item, index) => (
<li key={index}>{item.name}</li>
))}
</ul>
);
}🎯 Practical Example
Complete Form Component
jsx
function ContactForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
message: ''
});
const [errors, setErrors] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]: value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
setIsSubmitting(true);
// Form validation and submission logic
setTimeout(() => {
setIsSubmitting(false);
alert('Form submitted!');
}, 1000);
};
return (
<form onSubmit={handleSubmit} className="contact-form">
<div className="form-group">
<label htmlFor="name">Name</label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleChange}
required
/>
{errors.name && (
<span className="error">{errors.name}</span>
)}
</div>
<div className="form-group">
<label htmlFor="email">Email</label>
<input
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
required
/>
{errors.email && (
<span className="error">{errors.email}</span>
)}
</div>
<div className="form-group">
<label htmlFor="message">Message</label>
<textarea
id="message"
name="message"
value={formData.message}
onChange={handleChange}
rows="4"
required
/>
{errors.message && (
<span className="error">{errors.message}</span>
)}
</div>
<button
type="submit"
disabled={isSubmitting}
className={isSubmitting ? 'submitting' : ''}
>
{isSubmitting ? 'Submitting...' : 'Submit'}
</button>
</form>
);
}📝 Chapter Summary
JSX is at the core of React development, allowing us to describe UI in a declarative way. Mastering JSX syntax is an important step in learning React.
Key Takeaways
- ✅ JSX is a syntax extension for JavaScript, not a template language
- ✅ Use
{}to embed JavaScript expressions - ✅ JSX attributes use camelCase naming
- ✅ React automatically escapes content to prevent XSS attacks
- ✅ Must provide unique keys when rendering lists
- ✅ Keep JSX clean, extract complex logic to components or functions
Next Steps
In the next chapter, we'll learn about React component basics and how to create and use components.
Continue Learning: Next Chapter - React Component Basics