React applications rarely display the same content all the time.
A user might be logged in or logged out. A product might be available or sold out. A page might be loading data, showing an error, or displaying the actual content.
React allows you to display different UI based on these conditions. This is called conditional rendering.
For example:
const isLoggedIn = true;
return (
<div>
{isLoggedIn ? <h2>Welcome back!</h2> : <h2>Please log in.</h2>}
</div>
);
If isLoggedIn is true, React displays:
Welcome back!
If it is false, React displays:
Please log in.
Conditional rendering is one of the most important concepts in React because real applications constantly need to make decisions about what should appear on the screen.
What Is Conditional Rendering?
Conditional rendering means displaying different JSX depending on a condition.
The condition is usually based on:
- Variables
- Props
- State
- User actions
- API data
- Authentication status
- Form values
- Application settings
- Loading states
- Error states
For example:
const isOnline = true;
return (
<p>
{isOnline ? "Online" : "Offline"}
</p>
);
The value displayed depends on isOnline.
If:
isOnline = true
the result is:
Online
If:
isOnline = false
the result is:
Offline
Conditional Rendering With if
One of the simplest ways to conditionally render a component is with an if statement.
For example:
function Welcome({ isLoggedIn }) {
if (isLoggedIn) {
return <h2>Welcome back!</h2>;
}
return <h2>Please log in.</h2>;
}
Here, React returns one JSX structure when the condition is true and another when it is false.
You can use the component like this:
<Welcome isLoggedIn={true} />
This displays:
Welcome back!
And:
<Welcome isLoggedIn={false} />
displays:
Please log in.
Using if is particularly useful when the conditions are more complex or when an entire component needs to return different UI.
Conditional Rendering With if...else
You can use if...else when there are two possible outcomes.
function Account({ isLoggedIn }) {
if (isLoggedIn) {
return <h2>My Account</h2>;
} else {
return <h2>Login to continue</h2>;
}
}
The else block runs when the condition is false.
In React components, you will often see an even simpler version:
function Account({ isLoggedIn }) {
if (isLoggedIn) {
return <h2>My Account</h2>;
}
return <h2>Login to continue</h2>;
}
Once the first return executes, the component finishes, so an explicit else is not necessary.
Conditional Rendering With the Ternary Operator
The ternary operator is one of the most commonly used techniques for conditional rendering inside JSX.
Its syntax is:
condition ? valueIfTrue : valueIfFalse
For example:
const isLoggedIn = true;
return (
<div>
{isLoggedIn ? <h2>Dashboard</h2> : <h2>Login</h2>}
</div>
);
If the condition is true, React renders:
<h2>Dashboard</h2>
Otherwise:
<h2>Login</h2>
Ternary expressions are especially useful when you have exactly two possible UI outcomes.
Ternary Rendering With Text
The ternary operator does not always need to return JSX elements.
You can use it to choose text:
const isOnline = true;
<p>
{isOnline ? "User is online" : "User is offline"}
</p>
This is useful for labels, messages, button text, and status indicators.
For example:
<button>
{isSubscribed ? "Subscribed" : "Subscribe"}
</button>
The button text changes depending on the value of isSubscribed.
Conditional Rendering With &&
The logical AND operator can be used when you want to render something only when a condition is true.
For example:
const isAdmin = true;
return (
<div>
<h2>Dashboard</h2>
{isAdmin && <button>Admin Panel</button>}
</div>
);
If isAdmin is true, the button appears.
If isAdmin is false, the button does not appear.
This pattern is useful when there is no alternative UI to display.
For example:
{isLoggedIn && <LogoutButton />}
The LogoutButton appears only when the user is logged in.
Ternary vs &&
Both are useful, but they solve slightly different problems.
Use a ternary when there are two possible results:
{isLoggedIn ? <Dashboard /> : <Login />}
Use && when you only want to show something when a condition is true:
{isAdmin && <AdminPanel />}
A simple way to remember this is:
Ternary
True → this
False → that
&&
True → show this
False → show nothing
Rendering Nothing
Sometimes a component should render nothing under certain conditions.
You can return null.
function AdminPanel({ isAdmin }) {
if (!isAdmin) {
return null;
}
return <div>Admin Panel</div>;
}
When isAdmin is false, the component renders nothing.
This is useful when a component should completely disappear based on a condition.
Conditional Rendering With State
Conditional rendering becomes much more powerful when combined with React state.
For example:
import { useState } from "react";
function Toggle() {
const [isVisible, setIsVisible] = useState(false);
return (
<div>
<button onClick={() => setIsVisible(!isVisible)}>
Toggle
</button>
{isVisible && (
<p>
This content is now visible.
</p>
)}
</div>
);
}
Initially:
isVisible = false
so the paragraph is not displayed.
When the button is clicked:
isVisible = true
React renders the paragraph.
This is one of the most common patterns for interactive React interfaces.
Showing and Hiding Components
You can conditionally render entire components.
function App() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<>
{isLoggedIn ? (
<Dashboard />
) : (
<Login />
)}
</>
);
}
Only one of the two components is rendered at a time.
This pattern is commonly used for:
- Login pages
- User dashboards
- Protected interfaces
- Onboarding screens
- Account pages
Conditional Rendering With Props
Props can also control what a component displays.
function UserStatus({ isOnline }) {
return (
<div>
{isOnline ? (
<p>Online</p>
) : (
<p>Offline</p>
)}
</div>
);
}
Use it like this:
<UserStatus isOnline={true} />
Or:
<UserStatus isOnline={false} />
The parent component controls the value, while the child component decides what to display.
Conditional Classes
Conditions can also control CSS classes.
const isActive = true;
<div
className={isActive ? "card active" : "card"}
>
React Course
</div>
When isActive is true:
card active
When false:
card
This allows the appearance of a component to change according to its state.
Conditional Attributes
You can conditionally change attributes as well.
For example:
const isDisabled = true;
<button disabled={isDisabled}>
Submit
</button>
You can also dynamically select an image:
const isDarkMode = true;
<img
src={
isDarkMode
? "/dark-logo.png"
: "/light-logo.png"
}
alt="Website logo"
/>
The same principle applies to many JSX attributes.
Multiple Conditions
Sometimes you have more than two possible states.
For example, consider an order:
const status = "shipped";
You could use multiple conditions:
function OrderStatus({ status }) {
if (status === "pending") {
return <p>Order is being processed.</p>;
}
if (status === "shipped") {
return <p>Order has been shipped.</p>;
}
if (status === "delivered") {
return <p>Order has been delivered.</p>;
}
return <p>Unknown order status.</p>;
}
This is often easier to understand than creating a very large nested ternary expression.
Nested Ternary Operators
Technically, you can write multiple ternary conditions:
<p>
{status === "pending"
? "Processing"
: status === "shipped"
? "Shipped"
: "Delivered"}
</p>
This works, but deeply nested ternaries can quickly become difficult to read.
For example:
condition1
? result1
: condition2
? result2
: condition3
? result3
: result4
For several conditions, if statements or a clearer mapping structure are usually easier to maintain.
Conditional Rendering With Loading States
A very common React use case is displaying different content while data is loading.
function Users({ loading, users }) {
if (loading) {
return <p>Loading users...</p>;
}
return (
<ul>
{users.map((user) => (
<li key={user.id}>
{user.name}
</li>
))}
</ul>
);
}
The UI has two states:
Loading
↓
Display loading message
and:
Loading finished
↓
Display users
Real applications often have even more states, such as loading, success, empty, and error.
Loading, Error, Empty, and Success States
A more realistic component might handle several states.
function UserList({ loading, error, users }) {
if (loading) {
return <p>Loading...</p>;
}
if (error) {
return <p>Something went wrong.</p>;
}
if (users.length === 0) {
return <p>No users found.</p>;
}
return (
<ul>
{users.map((user) => (
<li key={user.id}>
{user.name}
</li>
))}
</ul>
);
}
This is a practical example of conditional rendering in real applications.
The component can display:
Loading
or:
Error
or:
No users found
or:
User list
depending on the current data.
Conditional Rendering With Optional Data
When working with data that may not exist yet, you can use optional chaining.
<p>
{user?.name}
</p>
If user exists, React can access:
user.name
If user is null or undefined, the expression safely evaluates without trying to access a property from a missing object.
You can also provide a fallback:
<p>
{user?.name || "Guest"}
</p>
This displays "Guest" when user?.name is falsy.
Conditional Rendering With Arrays
You can conditionally display content based on whether an array contains items.
const users = [];
return (
<div>
{users.length > 0 ? (
<UserList users={users} />
) : (
<p>No users found.</p>
)}
</div>
);
This is a common pattern for empty states.
Another approach is:
{users.length === 0 && (
<p>No users found.</p>
)}
Avoiding Accidental Rendering of Numbers
There is an important detail when using && in JSX.
Consider:
const count = 0;
return (
<div>
{count && <p>There are items.</p>}
</div>
);
Because count is 0, the expression evaluates to 0.
React can render that 0 on the screen.
You might therefore see:
0
when you expected nothing.
A safer approach is to use an explicit comparison:
{count > 0 && (
<p>There are items.</p>
)}
Now the condition produces a boolean.
Conditional Rendering With null
Another common pattern is to explicitly render nothing.
function Notification({ message }) {
if (!message) {
return null;
}
return (
<div>
{message}
</div>
);
}
If there is no message, React renders nothing for this component.
This is useful for optional UI such as:
- Notifications
- Badges
- Error messages
- Tooltips
- Admin controls
- Optional sections
Using Variables for Conditional JSX
When conditional logic becomes more complex, you can calculate the JSX before the return statement.
function Dashboard({ isLoggedIn, isAdmin }) {
let content;
if (!isLoggedIn) {
content = <Login />;
} else if (isAdmin) {
content = <AdminDashboard />;
} else {
content = <UserDashboard />;
}
return (
<main>
{content}
</main>
);
}
This can make the component easier to read because the decision-making logic is separated from the main JSX structure.
Conditional Rendering With Functions
You can also move complex rendering logic into a function.
function getStatusMessage(status) {
if (status === "pending") {
return "Your order is being processed.";
}
if (status === "shipped") {
return "Your order is on the way.";
}
if (status === "delivered") {
return "Your order has arrived.";
}
return "Unknown status.";
}
Then:
function Order({ status }) {
return (
<p>
{getStatusMessage(status)}
</p>
);
}
This approach can keep complicated decisions outside the JSX.
Conditional Rendering Best Practices
Keep simple conditions simple
For a basic two-way decision:
{isLoggedIn ? <Dashboard /> : <Login />}
is clear and readable.
Use if for complex decisions
When several states need to be handled:
if (loading) {
...
}
if (error) {
...
}
if (empty) {
...
}
is often clearer than nested ternaries.
Avoid deeply nested ternaries
Instead of:
condition1
? ...
: condition2
? ...
: condition3
? ...
: ...
consider using if statements or separate rendering functions.
Make conditions meaningful
Prefer:
{isLoggedIn && <Dashboard />}
over complicated expressions that are difficult to understand.
Handle all important UI states
When displaying API data, think about:
Loading
Error
Empty
Success
A good React interface should account for each relevant state.
A Complete Practical Example
Here is a small dashboard that handles several UI states:
import { useState } from "react";
function Dashboard() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [isAdmin, setIsAdmin] = useState(false);
if (!isLoggedIn) {
return (
<div>
<h1>Welcome</h1>
<p>
Please log in to continue.
</p>
<button onClick={() => setIsLoggedIn(true)}>
Log In
</button>
</div>
);
}
return (
<div>
<h1>Dashboard</h1>
<p>
You are logged in.
</p>
{isAdmin && (
<button>
Open Admin Panel
</button>
)}
<button
onClick={() => setIsLoggedIn(false)}
>
Log Out
</button>
</div>
);
}
export default Dashboard;
This example demonstrates several important React concepts:
- State
ifstatements&&- Event handlers
- Conditional components
- Conditional buttons
- Different UI states
When the user is logged out, the login interface appears.
After logging in, the dashboard appears.
If the user is an administrator, the Admin Panel button appears as well.
Conditional Rendering Cheat Sheet
| Situation | Pattern |
|---|---|
| Two possible UI results | condition ? <A /> : <B /> |
| Show only when true | condition && <A /> |
| Complex conditions | if statements |
| Render nothing | return null |
| Conditional text | {condition ? "Yes" : "No"} |
| Conditional class | className={condition ? "active" : "inactive"} |
| Conditional attribute | disabled={condition} |
| Loading state | if (loading) return <Loading /> |
| Error state | if (error) return <Error /> |
| Empty state | if (items.length === 0) ... |
| Multiple states | if / else if / else |
Common Mistakes
Using if directly inside JSX
This is not valid:
return (
<div>
{if (isLoggedIn) {
return <Dashboard />;
}}
</div>
);
JavaScript if statements cannot be placed directly inside JSX expressions.
Instead, use a ternary:
return (
<div>
{isLoggedIn ? <Dashboard /> : <Login />}
</div>
);
Or move the if statement outside the JSX.
Using && When You Need an Else Case
This:
{isLoggedIn && <Dashboard />}
only renders the dashboard when the condition is true.
If you need another UI when false, use a ternary:
{isLoggedIn ? <Dashboard /> : <Login />}
Accidentally Rendering 0
Be careful with:
{count && <p>Items available</p>}
when count is 0.
Prefer:
{count > 0 && <p>Items available</p>}
Overusing Nested Ternaries
Nested ternaries can make JSX difficult to understand.
If you have several conditions, move the logic into if statements or a separate function.
Forgetting Loading and Error States
When working with asynchronous data, do not only handle the successful result.
Consider:
Loading
Error
Empty
Success
These states are common in real-world applications.
Where to Place an Image
Place this image after the section “Ternary Rendering With Text”.
Create a 16:9 React educational infographic showing conditional rendering:
isLoggedIn
│
┌─────┴─────┐
TRUE FALSE
│ │
▼ ▼
<Dashboard /> <Login />
Also show the JSX expression:
{isLoggedIn ? <Dashboard /> : <Login />}
Use a polished modern React developer aesthetic, clean code-editor styling, clear TRUE/FALSE branches, and a visually simple flow diagram.
Caption: Conditional rendering with the ternary operator in React
Alt text: React conditional rendering flow showing Dashboard for logged-in users and Login for logged-out users
Practice Exercise
Build a UserPanel component that receives:
isLoggedIn
The component should behave like this:
When the user is logged out:
Please log in
[Log In]
When the user is logged in:
Welcome back!
[View Profile]
[Log Out]
Then add another prop:
isAdmin
If the user is an administrator, display:
[Admin Panel]
Use:
if- Ternary rendering
&&- React state
Try building it yourself before checking a solution.
Key Takeaways
- Conditional rendering allows React to display different UI based on data or conditions.
ifstatements are useful for complex rendering decisions.- The ternary operator is useful when there are two possible outcomes.
&&is useful when something should appear only when a condition is true.nullcan be returned when a component should render nothing.- Conditions can control components, text, classes, attributes, and entire sections of an interface.
- React state and props are commonly used as the source of conditional values.
- Loading, error, empty, and success states are important in real applications.
- Avoid deeply nested ternary expressions because they become difficult to maintain.
- Be careful when using
&&with numbers such as0. - Move complicated conditional logic outside JSX when it improves readability.
- Conditional rendering is essential for creating interactive and data-driven React applications.
The core idea is simple:
{condition ? <ComponentA /> : <ComponentB />}
React evaluates the condition and renders the appropriate UI. This simple concept becomes the foundation for handling different application states throughout a React project.