What is Conditional Rendering?
Conditional rendering means showing different content based on certain conditions - like showing a login button if the user is logged out, or a welcome message if they're logged in.
Real-World Examples:
- Show loading spinner while fetching data
- Display different UI for admin vs regular users
- Show error messages when something goes wrong
- Hide/show sections based on user actions
🎯 If/Else with Return
The simplest approach - use regular JavaScript if statements:
function Greeting({ isLoggedIn }) {
if (isLoggedIn) {
return <h1>Welcome back!</h1>;
}
return <h1>Please log in.</h1>;
}
// Usage
<Greeting isLoggedIn={true} /> // Shows "Welcome back!"
<Greeting isLoggedIn={false} /> // Shows "Please log in."
With Multiple Conditions:
function UserStatus({ status }) {
if (status === 'loading') {
return <p>Loading...</p>;
}
if (status === 'error') {
return <p>Error occurred!</p>;
}
if (status === 'success') {
return <p>Data loaded successfully!</p>;
}
return <p>Unknown status</p>;
}
❓ Ternary Operator (Inline)
Perfect for simple conditions inside JSX:
function LoginButton({ isLoggedIn }) {
return (
<div>
{isLoggedIn ? (
<button>Logout</button>
) : (
<button>Login</button>
)}
</div>
);
}
// Shorter version for simple elements
function Status({ isActive }) {
return (
<p>Status: {isActive ? 'Active' : 'Inactive'}</p>
);
}
Nested Ternaries (Use Sparingly):
function Score({ score }) {
return (
<div>
Grade: {
score >= 90 ? 'A' :
score >= 80 ? 'B' :
score >= 70 ? 'C' :
score >= 60 ? 'D' : 'F'
}
</div>
);
}
// Better approach - use function
function Score({ score }) {
const getGrade = () => {
if (score >= 90) return 'A';
if (score >= 80) return 'B';
if (score >= 70) return 'C';
if (score >= 60) return 'D';
return 'F';
};
return <div>Grade: {getGrade()}</div>;
}
✅ Logical && Operator
Show something only if condition is true (no else case):
function Notifications({ count }) {
return (
<div>
<h2>Inbox</h2>
{count > 0 && (
<span className="badge">{count} new messages</span>
)}
</div>
);
}
// Multiple conditions
function UserProfile({ user, isAdmin }) {
return (
<div>
<h2>{user.name}</h2>
{user.isVerified && <span>✓ Verified</span>}
{user.isPremium && <span>⭐ Premium</span>}
{isAdmin && <button>Admin Panel</button>}
</div>
);
}
⚠️ Be Careful with Falsy Values!
// ❌ Shows "0" if count is 0
{count && <p>{count} items</p>}
// ✅ Correct - explicit check
{count > 0 && <p>{count} items</p>}
🔄 Rendering Nothing
Return null to render nothing:
function WarningBanner({ show, message }) {
if (!show) {
return null; // Component renders nothing
}
return (
<div className="warning">
⚠️ {message}
</div>
);
}
// Usage
<WarningBanner show={false} message="Error!" /> // Renders nothing
<WarningBanner show={true} message="Error!" /> // Shows warning
🎨 Conditional CSS Classes
function Button({ isPrimary, isDisabled, children }) {
// Method 1: Template literal
const className = `btn ${isPrimary ? 'btn-primary' : 'btn-secondary'} ${isDisabled ? 'disabled' : ''}`;
return (
<button className={className} disabled={isDisabled}>
{children}
</button>
);
}
// Method 2: Array join
function Card({ isActive, isHighlighted }) {
const classes = [
'card',
isActive && 'active',
isHighlighted && 'highlighted'
].filter(Boolean).join(' ');
return <div className={classes}>...</div>;
}
🔄 Loading States
function DataDisplay() {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
// Simulate data fetch
useEffect(() => {
setTimeout(() => {
// Simulate success or error
if (Math.random() > 0.3) {
setData({ name: 'John', age: 30 });
} else {
setError('Failed to load data');
}
setIsLoading(false);
}, 2000);
}, []);
// Loading state
if (isLoading) {
return (
<div className="spinner">
<p>Loading...</p>
</div>
);
}
// Error state
if (error) {
return (
<div className="error">
<p>❌ {error}</p>
<button onClick={() => window.location.reload()}>
Retry
</button>
</div>
);
}
// Success state
return (
<div className="data">
<h2>{data.name}</h2>
<p>Age: {data.age}</p>
</div>
);
}
🔐 Authentication Example
function App() {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
// Simulate checking auth status
useEffect(() => {
setTimeout(() => {
// Simulate logged in user
setUser({
name: 'Alice',
role: 'admin',
avatar: 'avatar.jpg'
});
setIsLoading(false);
}, 1000);
}, []);
if (isLoading) {
return <div>Checking authentication...</div>;
}
return (
<div>
{user ? (
<div>
{/* Logged in view */}
<header>
<h1>Welcome, {user.name}!</h1>
<img src={user.avatar} alt={user.name} />
{/* Admin-only section */}
{user.role === 'admin' && (
<button>Admin Dashboard</button>
)}
<button onClick={() => setUser(null)}>Logout</button>
</header>
<main>
<h2>Dashboard</h2>
<p>Your content here...</p>
</main>
</div>
) : (
<div>
{/* Logged out view */}
<h1>Please Log In</h1>
<button onClick={() => setUser({ name: 'Guest', role: 'user' })}>
Login
</button>
</div>
)}
</div>
);
}
📋 List with Conditional Items
function TaskList() {
const [showCompleted, setShowCompleted] = useState(true);
const [tasks, setTasks] = useState([
{ id: 1, text: 'Learn React', completed: true },
{ id: 2, text: 'Build Project', completed: false },
{ id: 3, text: 'Deploy App', completed: true }
]);
// Filter tasks based on showCompleted
const filteredTasks = showCompleted
? tasks
: tasks.filter(task => !task.completed);
return (
<div>
<h2>My Tasks</h2>
{/* Toggle button */}
<label>
<input
type="checkbox"
checked={showCompleted}
onChange={(e) => setShowCompleted(e.target.checked)}
/>
Show completed tasks
</label>
{/* Empty state */}
{filteredTasks.length === 0 ? (
<p>No tasks to show</p>
) : (
<ul>
{filteredTasks.map(task => (
<li
key={task.id}
className={task.completed ? 'completed' : ''}
>
{task.text}
{task.completed && ' ✓'}
</li>
))}
</ul>
)}
{/* Task count */}
<p>
{tasks.filter(t => !t.completed).length} tasks remaining
</p>
</div>
);
}
🎯 Complete Example: Dashboard
function Dashboard() {
const [user, setUser] = useState({
name: 'John Doe',
role: 'premium',
notifications: 5,
isOnline: true
});
const [view, setView] = useState('overview'); // 'overview', 'profile', 'settings'
const [showNotifications, setShowNotifications] = useState(false);
return (
<div className="dashboard">
{/* Header */}
<header>
<h1>Dashboard</h1>
{/* Online status */}
<span className={user.isOnline ? 'online' : 'offline'}>
{user.isOnline ? '🟢 Online' : '⚪ Offline'}
</span>
{/* Notifications */}
<div className="notifications">
<button onClick={() => setShowNotifications(!showNotifications)}>
🔔
{user.notifications > 0 && (
<span className="badge">{user.notifications}</span>
)}
</button>
{showNotifications && (
<div className="notification-dropdown">
{user.notifications === 0 ? (
<p>No new notifications</p>
) : (
<p>You have {user.notifications} new notifications</p>
)}
</div>
)}
</div>
</header>
{/* Navigation */}
<nav>
<button
className={view === 'overview' ? 'active' : ''}
onClick={() => setView('overview')}
>
Overview
</button>
<button
className={view === 'profile' ? 'active' : ''}
onClick={() => setView('profile')}
>
Profile
</button>
<button
className={view === 'settings' ? 'active' : ''}
onClick={() => setView('settings')}
>
Settings
</button>
</nav>
{/* Main content - conditional rendering */}
<main>
{view === 'overview' && (
<div>
<h2>Overview</h2>
{/* Premium badge */}
{user.role === 'premium' && (
<div className="premium-badge">
⭐ Premium Member
</div>
)}
<p>Welcome back, {user.name}!</p>
</div>
)}
{view === 'profile' && (
<div>
<h2>Profile</h2>
<p>Name: {user.name}</p>
<p>Role: {user.role}</p>
</div>
)}
{view === 'settings' && (
<div>
<h2>Settings</h2>
{user.role !== 'admin' ? (
<p>Some settings require admin access</p>
) : (
<button>Advanced Settings</button>
)}
</div>
)}
</main>
</div>
);
}
⚠️ Common Patterns
Empty States:
function ItemList({ items }) {
return (
<div>
{items.length === 0 ? (
<div className="empty-state">
<p>No items found</p>
<button>Add First Item</button>
</div>
) : (
<ul>
{items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
)}
</div>
);
}
Feature Flags:
function App() {
const features = {
darkMode: true,
betaFeatures: false,
analytics: true
};
return (
<div>
{features.darkMode && <DarkModeToggle />}
{features.betaFeatures && <BetaFeatures />}
{features.analytics && <Analytics />}
</div>
);
}
🎯 Key Takeaways
- If/else: Use before return for early returns
- Ternary ?: Perfect for inline conditions
- Logical &&: Show something only if condition is true
- Return null: Render nothing
- Loading states: Always handle loading/error/success
- Empty states: Show helpful message when no data
- Conditional classes: Change styling based on state
- Be explicit: Use
count > 0not justcount