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:

  • 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 render 0. Use count > 0 && ... instead of count && ....

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:

{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:

{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.

{count>0&&<p>Count: {count}</p>}

Mistake 2: Nesting too many ternaries

What you might do:

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 0 appears in the UI unexpectedly, check for value && <Component />. Use a boolean comparison like value > 0.
  • If the wrong branch renders, confirm the condition matches the real data type. Arrays use .length, objects may need Object.keys(obj).length.
  • If the UI flickers between loading and content, check that your status state 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 like 0.