Conditional Rendering in React
Conditional rendering in React works exactly the same way conditions work in JavaScript. You use JavaScript operators to create elements representing the current state, and let React update the UI to match them.
Mastering the different patterns of conditional rendering is crucial for writing clean, readable, and bug-free React components.
1. if/else Statements
The most basic way to conditionally render content is using standard JavaScript if/else blocks outside of the JSX return statement. This is best used when rendering entirely different component trees based on a condition.
function UserProfile({ isLoggedIn, user }) {
if (isLoggedIn) {
return <Dashboard user={user} />;
} else {
return <LoginPrompt />;
}
}
2. Ternary Operator (condition ? true : false)
For inline conditional rendering within JSX, the ternary operator is the most common and versatile choice. It allows you to concisely return one of two elements.
function AuthButton({ isLoggedIn }) {
return (
<button>
{isLoggedIn ? 'Logout' : 'Login'}
</button>
);
}
Ternaries are excellent for toggling classes, styles, or small pieces of text. However, avoid nesting ternaries, as they quickly become unreadable.
3. Logical AND (&&)
When you want to render something if a condition is true, and render nothing if it is false, the logical && operator is the cleanest approach.
function NotificationBar({ unreadMessages }) {
return (
<div>
<h2>Inbox</h2>
{/* If unreadMessages > 0, the badge is rendered. Otherwise, nothing is rendered. */}
{unreadMessages > 0 && (
<span className="badge">You have {unreadMessages} new messages!</span>
)}
</div>
);
}
⚠️ Warning with Logical &&:
In JavaScript, 0 && <Component /> evaluates to 0, and React will render the number 0 on the screen. To prevent this, ensure the left side of the && is a strict boolean.
// Bad: Renders "0" if items array is empty
{items.length && <List items={items} />}
// Good: Evaluates to false, renders nothing
{items.length > 0 && <List items={items} />}
4. Nullish Coalescing (??) and Optional Chaining (?.)
When dealing with data that might be null or undefined (often from APIs), modern JavaScript operators are incredibly useful in React.
The nullish coalescing operator (??) returns the right-hand operand when the left-hand is null or undefined.
function UserGreeting({ user }) {
// If user.displayName is null/undefined, use 'Guest'
const name = user?.displayName ?? 'Guest';
return <h1>Welcome, {name}!</h1>;
}
5. switch Statements
When you have multiple mutually exclusive conditions (e.g., handling different statuses like 'idle', 'loading', 'success', 'error'), switch statements or object maps are much cleaner than chained if/else or ternary operators.
function DataState({ status, data, error }) {
switch (status) {
case 'loading':
return <Spinner />;
case 'error':
return <ErrorMessage error={error} />;
case 'success':
return <DataView data={data} />;
default:
return null;
}
}
Alternative: Object Mapping
Instead of a switch, you can use an object dictionary to map states to components. This is often cleaner for simple renders.
const statusComponents = {
loading: <Spinner />,
error: <ErrorMessage />,
success: <DataView />,
};
function DataState({ status }) {
return statusComponents[status] || null;
}
Summary
- Use
if/elsefor early returns or entirely different views. - Use Ternary (
? :) for toggling between two UI states inline. - Use Logical AND (
&&) for rendering something vs. nothing. (Beware of0!) - Use Nullish Coalescing (
??) for falling back fromnull/undefineddata. - Use
switchor Object maps for complex state machines or multiple conditions.