Chapter 7: Conditional Rendering
1. What is Conditional Rendering?
Conditional rendering means showing different JSX based on a condition. In React, you never use if statements directly inside JSX (because JSX is not JavaScript code block). Instead, we use JavaScript expressions that return JSX (or null or nothing).
The 3 most common & clean ways in 2026:
| Method | Best used when… | Example syntax |
|---|---|---|
| Ternary operator | Show one thing OR another thing | {condition ? <ThingA /> : <ThingB />} |
| && operator | Show something only if condition is true | {condition && <Thing />} |
| If-else outside JSX | Complex logic or multiple branches | Write if before return |
2. Ternary Operator (Most Common & Readable)
Syntax:
|
0 1 2 3 4 5 6 |
{condition ? <ComponentA /> : <ComponentB />} |
Real example: Login / Logout button
Create src/components/AuthButton.tsx
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
import { useState } from 'react'; function AuthButton() { const [isLoggedIn, setIsLoggedIn] = useState(false); return ( <div style={{ padding: '40px', textAlign: 'center' }}> <h2>Authentication Example</h2> {isLoggedIn ? ( <div> <p style={{ fontSize: '20px', color: '#4ecdc4' }}> Welcome back, Webliance! 🎉 </p> <button onClick={() => setIsLoggedIn(false)} style={{ padding: '12px 30px', background: '#ff6b6b', color: 'white', border: 'none', borderRadius: '8px', fontSize: '18px', cursor: 'pointer' }} > Logout </button> </div> ) : ( <div> <p style={{ fontSize: '20px' }}>Please sign in</p> <button onClick={() => setIsLoggedIn(true)} style={{ padding: '12px 30px', background: '#646cff', color: 'white', border: 'none', borderRadius: '8px', fontSize: '18px', cursor: 'pointer' }} > Login </button> </div> )} {/* Bonus: Show different message based on login state */} <p style={{ marginTop: '30px' }}> {isLoggedIn ? 'You are logged in ✅' : 'You are logged out ❌'} </p> </div> ); } export default AuthButton; |
3. && Operator (Show ONLY if condition is true)
Syntax:
|
0 1 2 3 4 5 6 |
{condition && <Component />} |
Short-circuit evaluation: If condition is false, nothing after && is rendered.
Real example: Loading Spinner + Error Message
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
import { useState, useEffect } from 'react'; function UserProfile() { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); useEffect(() => { // Simulate API call setTimeout(() => { try { // Fake successful fetch setUser({ name: 'Webliance', city: 'Mumbai' }); } catch (err) { setError('Failed to load user data'); } finally { setLoading(false); } }, 1500); }, []); return ( <div style={{ padding: '40px', textAlign: 'center' }}> <h2>User Profile</h2> {/* Loading spinner */} {loading && ( <div style={{ fontSize: '24px', margin: '40px 0' }}> Loading user data... ⏳ </div> )} {/* Error message */} {error && ( <div style={{ color: '#ff6b6b', fontSize: '18px', background: '#fff0f0', padding: '16px', borderRadius: '8px', margin: '20px 0' }}> {error} 😔 </div> )} {/* Success content - only shows if user exists and no error */} {user && !loading && !error && ( <div style={{ background: '#f0f4ff', padding: '30px', borderRadius: '12px', maxWidth: '500px', margin: '0 auto' }}> <h3>Hello, {user.name}!</h3> <p>From: {user.city}</p> <p style={{ color: '#4ecdc4', fontWeight: 'bold' }}> Profile loaded successfully! 🎉 </p> </div> )} </div> ); } export default UserProfile; |
4. If-Else Outside JSX (For Complex Logic)
Sometimes you want to decide what to return before the return statement.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
function Greeting({ isMorning }: { isMorning: boolean }) { if (isMorning) { return ( <div style={{ padding: '40px', textAlign: 'center' }}> <h1>Good Morning, Webliance! ☀️</h1> <p>Have a fantastic day!</p> </div> ); } return ( <div style={{ padding: '40px', textAlign: 'center' }}> <h1>Good Evening, Webliance! 🌙</h1> <p>Relax and enjoy the night!</p> </div> ); } |
5. Conditional Rendering of Lists
Very common: show a list only if there are items, otherwise show “empty state”.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
function TodoList() { const [todos, setTodos] = useState<string[]>([ 'Learn React', 'Build awesome projects', 'Get job at top company' ]); return ( <div style={{ padding: '40px', maxWidth: '600px', margin: '0 auto' }}> <h2>My Todos</h2> {todos.length > 0 ? ( <ul style={{ listStyle: 'none', padding: 0 }}> {todos.map((todo, index) => ( <li key={index} style={{ padding: '12px', margin: '8px 0', background: '#f0f4ff', borderRadius: '8px', fontSize: '18px' }} > {todo} </li> ))} </ul> ) : ( <div style={{ textAlign: 'center', color: '#999', fontSize: '20px', padding: '60px 0' }}> No todos yet... Start adding some! 📝 </div> )} {/* Bonus: Add new todo button */} <button onClick={() => setTodos([...todos, 'New task'])} style={{ marginTop: '30px', padding: '12px 24px', background: '#646cff', color: 'white', border: 'none', borderRadius: '8px', fontSize: '18px', cursor: 'pointer' }} > Add Random Todo </button> </div> ); } |
Summary – Chapter 7 Key Takeaways
- Use ternary? : when you want to choose between two things
- Use && when you want to show something only if condition is true
- Put complex logic with if/elsebefore the return statement
- For lists → check length first → show list or empty state message
- Return null if you want to show nothing at all
- All conditions must be JavaScript expressions (no statements like if inside JSX)
Mini Homework Create a ProductCard component that:
- Takes props: name, price, inStock (boolean)
- Shows:
- Green “In Stock” badge if inStock === true
- Red “Out of Stock” badge if false
- “Add to Cart” button only if inStock === true
- Grayed out button + message if out of stock
