Conditional rendering in React means showing or doing something only when a condition is true. It works just like JavaScript's if statement, but applied inside JSX. React provides several patterns for this — each suited to different levels of complexity.
1. Ternary Operator
The most common pattern. Used when you want to render one thing if a condition is true and something else if it is false.
{condition ? <p>Yes</p> : <p>No</p>}
Full example:
import { useState } from "react";
function LoginToggle() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<div>
<button onClick={() => setIsLoggedIn(!isLoggedIn)}>
{isLoggedIn ? "Logout" : "Login"}
</button>
{isLoggedIn ? (
<p>Welcome, Wariz 👑</p>
) : (
<p>Please log in to continue</p>
)}
</div>
);
}
export default LoginToggle;
2. The && Operator
Used when you want to render something only if a condition is true, and render nothing otherwise.
{isLoggedIn && <p>Welcome back</p>}
⚠️ The && Gotcha with Falsy Numbers
If the left side of && evaluates to 0, React will render 0 on the screen instead of rendering nothing. This is because 0 is a falsy value but also a valid JSX output.
// ❌ Renders "0" on screen when count is 0
{count && <p>You have {count} items</p>}
// ✅ Correct — convert to a boolean first
{count > 0 && <p>You have {count} items</p>}
Always use a proper boolean expression on the left side of && to avoid this.
3. if Statements and Early Returns
For more complex conditions, you can use a regular if statement inside the component — before the return. Returning early with different JSX based on a condition is a clean and readable pattern.
function UserGreeting({ isLoggedIn }) {
if (!isLoggedIn) {
return <p>Please log in to continue.</p>;
}
return <p>Welcome back, Wariz 👑</p>;
}
This avoids deeply nested ternaries and keeps each case clearly separated.
4. Storing JSX in a Variable
For complex conditions, you can compute the JSX before the return statement and store it in a variable. This keeps the JSX itself clean and readable.
function StatusMessage({ status }) {
let message;
if (status === "loading") {
message = <p>Loading...</p>;
} else if (status === "error") {
message = <p>Something went wrong.</p>;
} else {
message = <p>Data loaded successfully.</p>;
}
return <div>{message}</div>;
}
This is especially useful when there are three or more conditions — using nested ternaries in JSX for this many cases becomes hard to read quickly.
5. Returning null
A component can return null to render nothing at all. This is useful when a component should be completely absent from the DOM under certain conditions.
function SuccessBanner({ show }) {
if (!show) return null;
return <div className="banner">Operation successful!</div>;
}
Returning null is clean and explicit — it clearly communicates the intent that nothing should be rendered.
Real-World Example: Loading and Error States
One of the most common uses of conditional rendering in production React is handling loading and error states when fetching data.
function UserProfile({ isLoading, hasError, user }) {
if (isLoading) {
return <p>Loading profile...</p>;
}
if (hasError) {
return <p>Failed to load profile. Please try again.</p>;
}
return (
<div>
<h2>{user.name}</h2>
<p>{user.role}</p>
</div>
);
}
Each state — loading, error, and success — gets its own clear branch. Early returns keep the happy path (the actual content) at the bottom, uncluttered.
Summary: When to Use Which Pattern
| Pattern | Best For |
|---|---|
Ternary (? :) | Two outcomes — show A or show B |
&& | One outcome — show A or show nothing |
Early return / if | Complex conditions or multiple branches |
| JSX variable | Three or more conditions, keeping JSX clean |
Return null | Completely hiding a component |