Ticker

6/recent/ticker-posts

🔀 React Conditional Rendering – Show the Right UI at the Right Time

🔀 React Conditional Rendering

😵 The Problem

Your React app rarely shows the same UI all the time.

A user might be logged in.

Or logged out.

A product might be available.

Or sold out.

Data might be loading.

Or it might have failed.

And sometimes there simply isn't any data to show.

So you end up with situations like:

User logged in    → Show Dashboard
User logged out   → Show Login
Loading           → Show Spinner
Error             → Show Error
No data           → Show Empty State

The UI isn't static anymore.

It depends on what is happening in your application.

That's where conditional rendering comes in.

💡 The Solution: Conditional Rendering

Conditional rendering simply means:

Render different UI depending on a condition.

For example:

function App() {
  const isLoggedIn = true;

  return (
    <div>
      {isLoggedIn ? (
        <h1>Welcome back!</h1>
      ) : (
        <h1>Please log in</h1>
      )}
    </div>
  );
}

If isLoggedIn is true, React renders:

Welcome back!

If it's false:

Please log in

Nothing magical is happening.

You're just using JavaScript logic to decide what React should render.

🔥 The Simplest Pattern: Ternary

The ternary operator is probably the most common way to handle simple conditions inside JSX.

{isLoggedIn ? <Dashboard /> : <Login />}

Think of it as:

condition
   ?
if true
   :
if false

It's perfect when you have exactly two possible UI states.

For example:

function Button({ isLoading }) {
  return (
    <button>
      {isLoading ? "Saving..." : "Save"}
    </button>
  );
}

Simple.

Readable.

No need for a giant if statement.

⚡ When You Only Need to Show Something

What if you don't need an else?

For example:

"Show this message only when the user is an admin."

You can use &&.

function Profile({ isAdmin }) {
  return (
    <div>
      <h1>Profile</h1>

      {isAdmin && (
        <button>Admin Settings</button>
      )}
    </div>
  );
}

If:

isAdmin === true

the button appears.

If:

isAdmin === false

React renders nothing for that expression.

This pattern is great for simple show/hide conditions.

⚠️ But && Has a Weird Edge Case

Here's one that catches people:

{count && <p>Items available</p>}

Looks fine.

But what happens when:

count = 0;

React can render the 0.

So you might suddenly see:

0

on your page.

😅

If 0 is a valid value, be explicit:

{count > 0 && (
  <p>Items available</p>
)}

This makes your intention much clearer.

🧠 Multiple Conditions

Real applications usually have more than two states.

Imagine a page that loads user data:

Loading
   ↓
Success
   ↓
Error

You could handle that with multiple conditions.

function UserProfile({
  isLoading,
  error,
  user
}) {
  if (isLoading) {
    return <p>Loading...</p>;
  }

  if (error) {
    return <p>Something went wrong.</p>;
  }

  if (!user) {
    return <p>User not found.</p>;
  }

  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  );
}

This is often cleaner than trying to squeeze everything into one giant JSX expression.

💡 Don't Be Afraid of if

A common mistake is thinking:

"I'm writing JSX, so I need to use ternaries everywhere."

Nope.

You can use normal JavaScript before the return.

function Dashboard({ user }) {
  if (!user) {
    return <Login />;
  }

  return <DashboardContent user={user} />;
}

This is called an early return.

And honestly, it's one of my favorite patterns when the conditions represent completely different screens.

Compare:

return (
  <div>
    {user ? (
      user.isAdmin ? (
        <AdminDashboard />
      ) : (
        <UserDashboard />
      )
    ) : (
      <Login />
    )}
  </div>
);

Yeah… technically valid.

But now you've created a ternary jungle. 🌴

The early-return version is much easier to read.

🔥 Conditional Rendering With Components

Conditional rendering becomes even more useful when you move UI into components.

Instead of:

function App() {
  return (
    <div>
      {isLoading && <Spinner />}
      {error && <ErrorMessage />}
      {user && <UserProfile user={user} />}
    </div>
  );
}

You can also create a dedicated component when the logic gets more complicated:

function UserContent({ isLoading, error, user }) {
  if (isLoading) {
    return <Spinner />;
  }

  if (error) {
    return <ErrorMessage />;
  }

  if (!user) {
    return <EmptyState />;
  }

  return <UserProfile user={user} />;
}

Now the parent doesn't need to know all the details.

Again, the goal isn't to create more components.

It's to make responsibilities obvious.

🎯 Real Example: Product Availability

Let's say you're building an e-commerce product card.

A product can have different states:

Available
Out of stock
Loading

You could write:

function ProductCard({ product, isLoading }) {
  if (isLoading) {
    return <p>Loading product...</p>;
  }

  if (!product) {
    return <p>Product not found.</p>;
  }

  return (
    <div>
      <h2>{product.name}</h2>

      <p>${product.price}</p>

      {product.stock > 0 ? (
        <button>Add to Cart</button>
      ) : (
        <button disabled>
          Out of Stock
        </button>
      )}
    </div>
  );
}

Notice how each condition has a clear purpose.

The component isn't trying to solve everything in one expression.

💡 Real Developer Insight

Here's something that becomes important as React applications grow:

Conditional rendering is easy. Conditional logic is not.

The problem usually starts when a component becomes something like:

return (
  <>
    {isLoading ? (
      <Spinner />
    ) : error ? (
      <Error />
    ) : user ? (
      user.isAdmin ? (
        <Admin />
      ) : user.isPremium ? (
        <PremiumUser />
      ) : (
        <RegularUser />
      )
    ) : (
      <Login />
    )}
  </>
);

Technically, it works.

But now you're reading a puzzle instead of reading UI code. 😅

When conditions start getting nested, step back.

Ask:

"Can I make these states explicit?"

Sometimes an early return is enough.

Sometimes a component should be extracted.

Sometimes the underlying state model needs improvement.

The goal isn't to write the shortest conditional.

The goal is to make the UI states obvious.

🧠 Another Important Point: Don't Duplicate UI

Imagine this:

if (isAdmin) {
  return (
    <div className="card">
      <h2>{user.name}</h2>
      <button>Edit</button>
    </div>
  );
}

return (
  <div className="card">
    <h2>{user.name}</h2>
  </div>
);

Now you have duplicated markup.

A better approach might be:

function UserCard({ user, isAdmin }) {
  return (
    <div className="card">
      <h2>{user.name}</h2>

      {isAdmin && (
        <button>Edit</button>
      )}
    </div>
  );
}

Same UI structure.

Only the changing part is conditional.

This makes future changes much safer.

⚠️ Common Developer Mistakes

1. Creating Giant Nested Ternaries

This:

{loading
  ? <Loading />
  : error
    ? <Error />
    : user
      ? <Profile />
      : <Login />
}

might be acceptable for a tiny case.

But once the logic grows, use early returns or split the UI.

2. Using && Without Thinking About Falsy Values

Be careful with:

{count && <List />}

If count is 0, you may render 0.

Prefer:

{count > 0 && <List />}

when that's what you actually mean.

3. Putting Complex Logic Directly Into JSX

This:

{
  users
    .filter(...)
    .sort(...)
    .map(...)
}

isn't automatically bad.

But if the expression becomes difficult to understand, move the logic outside the JSX.

4. Duplicating Large UI Blocks

Don't create two almost-identical versions of the same component just because one small part changes.

Keep the shared UI together and conditionally render the changing part.

5. Forgetting the "Empty" State

Developers usually think about:

Loading
Success
Error

But what about:

No results

Empty states are still application states.

Handle them intentionally.

🚀 Best Practice Summary

✅ Use ternaries for simple two-way UI decisions
✅ Use && for straightforward show-or-hide conditions
✅ Prefer early returns when entire screens have different states
✅ Keep complex conditional logic out of giant JSX expressions
✅ Design loading, error, empty, and success states intentionally

🎯 Conclusion

Conditional rendering isn't really about learning a few JavaScript operators.

It's about thinking in UI states.

A real application isn't simply:

Page

It's more like:

Loading
   ↓
Success
   ├── Data available
   └── Empty
   ↓
Error

Once you start thinking this way, your React components become much easier to design.

And when a conditional starts looking like a programming puzzle, that's usually your signal to step back and simplify it.

Readable UI logic beats clever JSX every time. 🚀

Reactions

Post a Comment

0 Comments