Beyond True and False: The Power of Conditional Rendering in React
In React, you don't just build static UIs; you build dynamic systems that respond to data. **Conditional rendering** is the set of techniques you use to decide *what* to show the user. It's not one single feature but a combination of JavaScript's logical operators used inside your JSX.
The `if/else` Statement (And Why It Doesn't Work in JSX)
Your first instinct might be to use a standard `if` statement. But if you try this, your code will break:
// ❌ This code will NOT work!
return (
<div>
if (isLoggedIn) {
<UserProfile />
} else {
<LoginForm />
}
</div>
)This fails because JSX curly braces `` can only contain **expressions** (things that evaluate to a value, like `1 + 1` or `user.name`), not **statements** (multi-line instructions like `if`, `for`, `switch`).
You *can* use `if/else` *before* the `return` statement to prepare variables, but a more direct approach is to use JavaScript expressions that *do* fit inside ``.
Tool 1: The Ternary Operator (`? :`) - The A/B Switch
This is the most common and direct replacement for an `if/else` block. It's an expression, so it works perfectly inside JSX.
return (
<div>
{isLoggedIn ? <UserProfile /> : <LoginForm />}
</div>
)Use this when you have **two distinct outcomes**: render A or render B.
Tool 2: Logical AND (`&&`) - The "Render or Nothing" Shortcut
Often, you don't have an "else" condition. You just want to show a component *if* a condition is true, and show *nothing* otherwise. This is where `&&` shines.
return (
<div>
{unreadMessages > 0 && <NotificationBell count={unreadMessages} />}
</div>
)This works because of "short-circuiting." If `unreadMessages > 0` is `false`, JavaScript doesn't even look at the part after `&&` and just returns `false`. React knows to render nothing for `false`. If it's `true`, JavaScript moves to the part after `&&` and returns the `NotificationBell` element, which React then renders.
The Critical Pitfall of `&&`: The '0' Bug
There's a major "gotcha" with `&&`. What if `unreadMessages` is `0`?
❌ Bad Practice
{unreadMessages && <NotificationBell />}
// If unreadMessages is 0......JavaScript evaluates `0 && ...`, which short-circuits to `0`. React **will render the `0`** to the screen! Your user will see a "0" on the page.
✔️ Good Practice
{unreadMessages > 0 && <NotificationBell />}
// or...
{Boolean(unreadMessages) && <NotificationBell />}By converting the number to a true boolean (`true` or `false`), you avoid the bug. `false` renders nothing, which is what you want.
Tool 3: Logical OR (`||`) & Coalescing (`??`) - The Fallbacks
These operators are perfect for providing default values.
- Logical OR (`||`): Returns the right-hand side if the left side is any **falsy** value (`0`, `""`, `false`, `null`, `undefined`).
{username || 'Guest'}(If `username` is `""`, it shows 'Guest') - Nullish Coalescing (`??`): This is a newer, often safer, alternative. It *only* returns the right-hand side if the left side is `null` or `undefined`.
{score ?? 0}(If `score` is `0`, it will correctly show `0`, not the fallback. `||` would incorrectly show the fallback.)
Key Takeaway: Always choose the right tool for the job.
• **Ternary (`? :`)** for A-or-B logic.
• **`&&`** for A-or-Nothing logic (and be careful of `0`!).
• **`??` or `||`** for providing fallback values.