Conditional Rendering

Reviewed & published by Brayan K

Conditional rendering means deciding what UI to show based on a condition. Because JSX is just an expression, you use ordinary JavaScript: the ternary cond ? a : b to pick between two things, the && operator to show something only when true, and a plain variable / early return when you have several cases.

Part of the free React course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

What You'll Learn

1️⃣ The Ternary — Pick One of Two

When you're choosing between exactly two things to render, reach for the ternary condition ? a : b. It's an expression, so it drops straight into JSX braces.

function Profile({ isLoggedIn }) {
  return (
    <div>
      {isLoggedIn ? <Dashboard /> : <LoginButton />}
    </div>
  );
}
// TERNARY: condition ? whenTrue : whenFalse  — choose one of two.
function greeting(isLoggedIn) {
  return isLoggedIn ? "Welcome back!" : "Please log in";
}

console.log(greeting(true));    // Welcome back!
console.log(greeting(false));   // Please log in

// In JSX:  {isLoggedIn ? <Dashboard /> : <LoginButton />}

2️⃣ The && Operator — Show or Show Nothing

When you want to show something only if a condition holds (and nothing otherwise), use cond && element. If the condition is false, React renders nothing. The classic bug: a number like 0 is falsy, so {count && <X/>} renders a literal 0. Always test a boolean: {count > 0 && <X/>}.

function Inbox({ unread }) {
  return (
    <div>
      {unread > 0 && <Badge count={unread} />}    
    </div>
  );
}
// && : show something ONLY when the condition is true.
// If the left side is false, React renders nothing.
function badge(unread) {
  return unread > 0 && (unread + " new");   // false OR the string
}

console.log(badge(3));   // 3 new
console.log(badge(0));   // false  -> in React this renders NOTHING

// ⚠️ The trap: {count && <X/>} renders a literal 0 when count is 0.
// Always use a boolean test:  count > 0 && <X/>
console.log(0 && "shown?");        // 0   <-  React would print this 0!
console.log(0 > 0 && "shown?");    // false  <- correct, renders nothing

Your turn — use a ternary and a safe &&:

// 🎯 YOUR TURN — fill in each ___ then press "Try it Yourself".
// 1) Use a TERNARY to return "On" when power is true, else "Off".
// 2) Use && to return the cartCount only when it is greater than 0.

function powerLabel(power) {
  return power ___ "On" ___ "Off";   // 👉 ? ... :
}

function cartBadge(cartCount) {
  return cartCount ___ 0 && cartCount;   // 👉 use > so 0 renders nothing
}

console.log(powerLabel(true));    // On
console.log(powerLabel(false));   // Off
console.log(cartBadge(5));        // 5
console.log(cartBadge(0));        // false

// ✅ Expected output:
//    On
//    Off
//    5
//    false

3️⃣ Many Cases — Variables & Early Returns

You can't put an if statement inside JSX braces (braces hold expressions, and if is a statement). For three or more branches, compute the element in a variable above the return, or use early returns — one per case. Far cleaner than nested ternaries.

function Status({ status }) {
  if (status === "loading") return <Spinner />;
  if (status === "error")   return <ErrorBox />;
  if (status === "empty")   return <EmptyState />;
  return <Results />;   // the default case
}
// MANY CASES: compute the UI above the return, then use the variable.
function statusLabel(status) {
  let label;
  if (status === "loading") label = "⏳ Loading";
  else if (status === "error") label = "❌ Error";
  else if (status === "empty") label = "📭 Nothing here";
  else label = "✅ Ready";
  return label;   // in JSX you'd put {label} or return <p>{label}</p>
}

console.log(statusLabel("loading"));   // ⏳ Loading
console.log(statusLabel("error"));     // ❌ Error
console.log(statusLabel("empty"));     // 📭 Nothing here
console.log(statusLabel("ok"));        // ✅ Ready

🧩 Reorder Challenge

These lines build a component that handles three states with early returns. Put them in the right order:

A.   if (error)   return <p>Error</p>;
B.   function View({ loading, error }) {
C.   return <p>Ready</p>;
D.   if (loading) return <p>Loading</p>;
E.   }

Common Errors (and the fix)

📋 Quick Reference

SituationTool
One of two things{ok ? <Yes /> : <No />}
Show only if true{count > 0 && <Badge />}
Hide a number-0 leak{count > 0 && ...}
Many casesif (x) return <A />; ...

🧠 Quick Recall

1. What does {0 && <Badge/>} render?

A literal 0 on screen. 0 is falsy so && returns 0, and React renders it. Use count > 0 &&.

2. You need to show a spinner OR the content — which tool?

A ternary: {loading ? <Spinner/> : <Content/>} — two branches, pick one.

3. Can you write {if (x) ...} inside JSX?

No. Braces hold expressions; if is a statement. Compute above the return or use a ternary.

Mini-Challenge: Notification Line

Build one display string per user combining a status dot, the name, and an unread count that only appears when greater than 0. Run it and check your output.

// 🎯 MINI-CHALLENGE: a notification line
//
// Given a user object, build ONE display string:
// 1. If user.isOnline, start with "🟢 ", else "⚫ ".
// 2. Add the user.name.
// 3. If user.unread > 0, append " (" + user.unread + ")".
//    (use && or a ternary; 0 must add nothing)
// 4. console.log the line for each user.
//
// ✅ Expected output:
//    🟢 Ada (3)
//    ⚫ Linus

const users = [
  { name: "Ada",   isOnline: true,  unread: 3 },
  { name: "Linus", isOnline: false, unread: 0 },
];

// your code here

🎉 Lesson Complete

Practice quiz

When should you use a ternary instead of && for conditional rendering?

  • When showing something or nothing
  • When rendering a list
  • When choosing between two different things to show
  • Never; they are identical

Answer: When choosing between two different things to show. Use a ternary (cond ? a : b) to pick between two outputs; use && to show one thing or nothing.

What does {count && <Badge />} render when count is 0?

  • A literal 0 on screen
  • Nothing
  • The Badge
  • undefined

Answer: A literal 0 on screen. 0 is falsy, so && evaluates to 0 and React renders the literal 0. Use {count > 0 && <Badge />}.

Why can't you put an if statement directly inside JSX braces?

  • if is too slow
  • React disables if in JSX
  • if only works in class components
  • JSX braces hold expressions, and if is a statement

Answer: JSX braces hold expressions, and if is a statement. Braces contain expressions. Compute the value with if above the return, or use a ternary inside the braces.

What is the cleanest way to handle three or more rendering cases?

  • Deeply nested ternaries
  • Early returns or a lookup object
  • Many && operators chained together
  • A single if with no else

Answer: Early returns or a lookup object. For 3+ branches, prefer early returns (one element per case) or a lookup object over nested ternaries.

Which renders nothing when the condition is false?

  • {cond && <X />}
  • {cond ? <X /> : <Y />}
  • {cond || <X />}
  • {!cond}

Answer: {cond && <X />}. cond && <X /> shows <X /> only when cond is true; when false, React renders nothing.

You need to show a Spinner OR the Content. Which tool fits best?

  • {loading && <Spinner/>}
  • An if inside the braces
  • A ternary: {loading ? <Spinner/> : <Content/>}
  • A key prop

Answer: A ternary: {loading ? <Spinner/> : <Content/>}. Two mutually exclusive branches call for a ternary with an explicit else.

How do you safely avoid the '0 leaks onto the screen' trap?

  • Use {count && ...}
  • Test a real boolean, e.g. {count > 0 && ...}
  • Wrap count in quotes
  • Use a ternary with no else

Answer: Test a real boolean, e.g. {count > 0 && ...}. Convert to a boolean test like count > 0 (or Boolean(count)) so a zero never renders.

With early returns ordering cases, how should you order them?

  • General case first, then specific
  • Alphabetically
  • Order does not matter
  • Specific cases first, then the general/default last

Answer: Specific cases first, then the general/default last. Earlier returns win, so check specific states (loading, error) first and fall through to the default.

JSX is fundamentally what, which is why ordinary JS decides rendering?

  • A template string
  • An expression
  • A statement
  • A CSS rule

Answer: An expression. JSX is just an expression, so you use normal JavaScript (ternary, &&, variables) to choose what to show.

You want a fallback for the false branch, but && shows nothing. What should you switch to?

  • Another &&
  • An if inside JSX braces
  • A ternary with an explicit else
  • A for loop

Answer: A ternary with an explicit else. && renders nothing when false. For an explicit alternative, use a ternary: cond ? a : b.

Continue this course

Frequently asked questions

When should I use && vs a ternary?

Use && when you want to show something or nothing (one branch). Use a ternary condition ? a : b when you're choosing between two different things to show.

Why does a 0 sometimes show up on my screen?

Because {count && <Badge/>} returns the number 0 when count is 0, and React renders 0. Use a real boolean test: {count > 0 && <Badge/>}, or convert with {Boolean(count) && ...}.

Can I use if/else inside JSX?

Not directly inside the braces — JSX braces hold expressions, and if is a statement. Compute the value with an if/else (or early return) ABOVE the return, then drop the variable into the JSX.

How do I handle many cases cleanly?

For 3+ branches, prefer an early-return pattern (return one element per case) or a lookup object mapping a key to an element, rather than deeply nested ternaries.

Related lessons