How to Use Conditional Rendering in React
What you’ll build or solve
You’ll control what appears on screen based on state or props.
When this approach works best
Conditional rendering works best when you need to:
Learn React on Mimo
- Show a loading spinner until data is ready, then show content.
- Display different UI for signed-in vs signed-out users.
- Hide parts of the interface until a condition is met, like a modal or dropdown.
Avoid stacking complex logic directly inside JSX. If the condition becomes hard to read, extract it into a variable or split the UI into smaller components.
Prerequisites
- A React app set up
- Basic JSX knowledge
- Familiarity with props and state
Step-by-step instructions
1) Use && for “render or nothing”
Use the logical AND operator when you want to render something only if a condition is true.
JavaScript
exportdefaultfunctionBanner({ show }) {
return (
<div>
{show&&<p>Free shipping this week</p>}
</div>
);
}
If show is true, the paragraph renders. If show is false, React renders nothing in that spot.
What to look for:
- The left side should be a boolean expression.
- If the left side can be
0, React may render0. Usecount > 0 && ...instead ofcount && ....
2) Use the ternary operator for “this or that”
Use a ternary when you need to choose between two UI branches.
JavaScript
exportdefaultfunctionAuthStatus({ signedIn }) {
return (
<p>
{signedIn?"Welcome back": "Please sign in"}
</p>
);
}
This always renders one of two outcomes.
You can also render full components:
Ruby
{signedIn?<Dashboard/>:<Login/>}
What to look for:
- Use a ternary when both outcomes must render something.
- Keep each branch short. If it grows, move logic above the
return.
3) Use early returns for multiple states
When you have mutually exclusive states like loading, error, and success, early returns keep JSX clean.
JavaScript
exportdefaultfunctionResults({ status, items }) {
if (status==="loading")return<p>Loading…</p>;
if (status==="error")return<p>Something went wrong.</p>;
if (!items.length)return<p>No results found.</p>;
return (
<ul>
{items.map((item) => (
<likey={item.id}>{item.label}</li>
))}
</ul>
);
}
Each state exits the component early. The success UI stays simple and unindented.
What to look for:
- Handle loading and error before rendering main content.
- Return only one branch per state.
Examples you can copy
Example 1: Toggle a dropdown
JavaScript
import {useState }from"react";
exportdefaultfunctionDropdown() {
const [open,setOpen]=useState(false);
return (
<div>
<buttononClick={() =>setOpen((o) =>!o)}>
{open?"Hide":"Show"} menu
</button>
{open&& (
<ul>
<li>Profile</li>
<li>Settings</li>
<li>Sign out</li>
</ul>
)}
</div>
);
}
Example 2: Signed-in vs signed-out UI
JavaScript
exportdefaultfunctionHome({ user }) {
returnuser? (
<div>
<h1>Welcome, {user.name}</h1>
<Dashboard/>
</div>
): (
<Login/>
);
}
Example 3: Loading, error, and data states
JavaScript
exportdefaultfunctionUsersPanel({ status, users }) {
if (status==="loading")return<Spinner/>;
if (status==="error")return<ErrorMessage/>;
returnusers.length? (
<ul>
{users.map((u) => (
<likey={u.id}>{u.name}</li>
))}
</ul>
): (
<p>No users yet.</p>
);
}
Common mistakes and how to fix them
Mistake 1: Using && with a value that can be 0
What you might do:
CSS
{count&&<p>Count: {count}</p>}
Why it breaks:
If count is 0, React renders 0 instead of hiding the element.
Fix: Make the condition explicit.
CSS
{count>0&&<p>Count: {count}</p>}
Mistake 2: Nesting too many ternaries
What you might do:
Ruby
returnstatus==="loading"
?<p>Loading…</p>
:status==="error"
?<p>Error</p>
:items.length
?<Listitems={items}/>
:<p>Empty</p>;
Why it breaks:
Nested ternaries are hard to read and easy to mis-edit.
Fix: Switch to early returns.
if (status==="loading")return<p>Loading…</p>;
if (status==="error")return<p>Error</p>;
if (!items.length)return<p>Empty</p>;
return<Listitems={items}/>;
Troubleshooting
- If
0appears in the UI unexpectedly, check forvalue && <Component />. Use a boolean comparison likevalue > 0. - If the wrong branch renders, confirm the condition matches the real data type. Arrays use
.length, objects may needObject.keys(obj).length. - If the UI flickers between loading and content, check that your
statusstate updates in the correct order. - If JSX becomes difficult to follow, move conditions into variables like
const isEmpty = items.length === 0;.
Quick recap
- Use
&&to render something or nothing. - Use a ternary for one of two outcomes.
- Use early returns for loading, error, empty, and success states.
- Avoid nested ternaries for complex logic.
- Watch for
&&with values like0.
Join 35M+ people learning for free on Mimo
4.8 out of 5 across 1M+ reviews
Check us out on Apple AppStore, Google Play Store, and Trustpilot