Learn how to render different UI elements based on conditions using ternary operators, logical AND, early returns, and more.
Real applications show different things depending on the situation — a login form when the user is not authenticated, a welcome message when they are, a loading spinner while data is being fetched, an error message when something goes wrong.
In React, conditional rendering means showing different elements or components based on some condition. Since JSX is just JavaScript expressions, you can use all of JavaScript's conditional logic to decide what to render.
There are several patterns for conditional rendering in React, each suited to different situations:
&&) — Show something or nothingLet's explore each of these patterns.
The ternary operator (condition ? ifTrue : ifFalse) is the most common way to conditionally render in JSX. It works directly inside curly braces and lets you choose between two pieces of JSX:
function LoginStatus({ isLoggedIn }) {
return (
<div>
{isLoggedIn ? (
<p>Welcome back, user!</p>
) : (
<p>Please log in.</p>
)}
</div>
);
}You can use ternaries anywhere in JSX — for entire elements, for text content, for attributes, or for component props:
function Button({ isPrimary }) {
return (
<button
className={isPrimary ? 'btn-primary' : 'btn-secondary'}
>
{isPrimary ? 'Save' : 'Cancel'}
</button>
);
}You can also nest ternaries, but this quickly becomes hard to read:
// Avoid deeply nested ternaries
{status === 'loading' ? (
<Spinner />
) : status === 'error' ? (
<Error />
) : (
<Content />
)}For more than two conditions, consider using early returns or a variable instead (covered in the next sections).
The ternary is best when you have exactly two alternatives and the logic is simple enough to read inline.
When you want to show something or show nothing, the logical AND operator (&&) is cleaner than a ternary with null:
function Notification({ message, show }) {
return (
<div>
<h1>Dashboard</h1>
{show && <p className="notification">{message}</p>}
</div>
);
}If show is true, React renders the <p> element. If show is false, React renders nothing.
This works because of how JavaScript's && operator evaluates:
true && <element> returns <element> (rendered)false && <element> returns false (React ignores false, null, and undefined)Watch out for the number zero! This is a common gotcha:
const count = 0;
// BUG: This renders "0" on screen, not nothing!
{count && <p>You have {count} items</p>}Why? Because 0 && <element> returns 0, and React does render the number 0. The fix is to make the condition explicitly boolean:
// CORRECT: Convert to boolean first
{count > 0 && <p>You have {count} items</p>}Use && when:
The && pattern is perfect for optional UI elements like error messages, badges, tooltips, or conditional sections.
Early returns let you handle special cases at the top of your component before reaching the main rendering logic:
function UserProfile({ user }) {
if (!user) {
return <p>No user found.</p>;
}
if (user.isBanned) {
return <p>This account has been suspended.</p>;
}
// Main rendering — only reached if user exists and is not banned
return (
<div>
<h2>{user.name}</h2>
<p>{user.bio}</p>
</div>
);
}Early returns are great when a condition means the component should render something completely different. They keep the main rendering logic clean and unindented.
Variable assignment is useful when the conditional logic is too complex for inline ternaries:
function StatusMessage({ status }) {
let content;
if (status === 'loading') {
content = <p>Loading...</p>;
} else if (status === 'error') {
content = <p>Something went wrong!</p>;
} else if (status === 'empty') {
content = <p>No data available.</p>;
} else {
content = <p>Here is your data.</p>;
}
return (
<div className="status">
<h2>Status</h2>
{content}
</div>
);
}You can also use a switch statement or even an object lookup for mapping values to components:
const icons = {
success: <span>Success</span>,
warning: <span>Warning</span>,
error: <span>Error</span>,
};
function StatusIcon({ type }) {
return icons[type] || <span>Unknown</span>;
}Rendering null makes a component render nothing:
function Warning({ show, message }) {
if (!show) return null;
return <p className="warning">{message}</p>;
}Returning null is a legitimate way to say "this component has nothing to display right now."
<div id="root"></div>
<script src="https://unpkg.com/react@19/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@19/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function App() {
const [isLoggedIn, setIsLoggedIn] = React.useState(false);
const [showDetails, setShowDetails] = React.useState(false);
return (
<div style={{ padding: "20px" }}>
<h1>Conditional Rendering Demo</h1>
{/* Ternary: show different content */}
{isLoggedIn ? (
<p>Welcome back, User!</p>
) : (
<p>Please log in to continue.</p>
)}
{/* Ternary: different button text */}
<button onClick={() => setIsLoggedIn(!isLoggedIn)}>
{isLoggedIn ? "Log Out" : "Log In"}
</button>
<hr />
{/* AND operator: show or hide */}
<button onClick={() => setShowDetails(!showDetails)}>
{showDetails ? "Hide" : "Show"} Details
</button>
{showDetails && (
<div style={{ marginTop: "10px", padding: "10px", background: "#f0f0f0" }}>
<p>Here are the extra details!</p>
<p>They only appear when the button is toggled.</p>
</div>
)}
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>What does `{count && <p>Items: {count}</p>}` render when count is 0?