Conditional Rendering

Course 1 · Ch 5
Conditional Rendering
Showing different JSX depending on the current state or props — there's no special syntax, just JavaScript

JSX doesn't have its own if tag or special conditional markup — conditional rendering is just regular JavaScript deciding what to return or embed. The LightSwitch and StatusLabel components from earlier chapters were already doing this with a ternary; this chapter covers the full range of patterns and when each one reads best.

if/else — Returning Different JSX Entirely

function Greeting({ isLoggedIn }) { if (isLoggedIn) { return <h2>Welcome back!</h2>; } return <h2>Please log in.</h2>; }

A plain if statement works fine above the final return, or as separate early returns like this — it just can't be written directly inside the JSX itself, since if is a statement, not an expression that produces a value.

The Ternary — Inline, Within JSX

function Greeting({ isLoggedIn }) { return ( <div> {isLoggedIn ? <h2>Welcome back!</h2> : <h2>Please log in.</h2>} </div> ); }

Because condition ? a : b is an expression — it produces a value — it can sit directly inside { } in the middle of JSX, unlike if. This is the most common conditional pattern in React precisely because of that: it fits inline without needing a separate return path.

&& — Rendering Something, or Nothing

function Inbox({ unreadCount }) { return ( <div> <h2>Inbox</h2> {unreadCount > 0 && <p>You have {unreadCount} unread messages.</p>} </div> ); }

condition && jsx renders the JSX only when condition is true — when it's false, JavaScript's short-circuit evaluation stops before ever reaching the JSX, and nothing extra renders. This reads more cleanly than a ternary specifically for the "show this, or show nothing" case, where a full ternary's : null would be redundant clutter.

The 0 && "text" trap
{unreadCount && <p>...</p>} looks identical to the version above but has a subtle bug: when unreadCount is exactly 0, && evaluates to 0 itself (not false) — and React does render a bare 0 on the page, unlike false/null/undefined, which render nothing. Writing an explicit comparison (unreadCount > 0 && ...) avoids the issue entirely by guaranteeing the left side is a real boolean.

Rendering Nothing At All

function Banner({ message }) { if (!message) { return null; } return <div className="banner">{message}</div>; }

A component returning null renders nothing at all into the DOM — no empty <div>, nothing. This is the standard way to write a component that sometimes shouldn't appear in the page at all, rather than appearing with empty content.

Several Possible States — A Mapped Lookup

function StatusBadge({ status }) { const labels = { pending: "⏳ Pending", shipped: "📦 Shipped", delivered: "✅ Delivered", }; return <span>{labels[status] ?? "Unknown"}</span>; }

Once there are more than two or three possible outcomes, a chain of ? : ternaries gets hard to read fast. A plain object used as a lookup table — keyed by the possible values — scales much better, with ?? (the nullish coalescing operator) providing a fallback for any value not found in the table.

PatternBest for
if / early returnEntirely different JSX depending on a condition
condition ? a : bInline either/or choice within JSX
condition && jsxShow something, or show nothing at all
return nullThe whole component should render nothing this time
Lookup objectThree or more named possible states

Coding Challenges

Challenge 1

Build a LoginButton component with isLoggedIn state (starting false). Use a ternary to show a "Log In" button when logged out and a "Log Out" button when logged in, each toggling the state when clicked.

📄 View solution
Challenge 2

Build a Cart component with an itemCount prop. Show "Your cart is empty" if itemCount is 0, otherwise show "You have N item(s) in your cart" using && correctly so 0 never renders by itself.

📄 View solution
Challenge 3

Build a TrafficLight component with a color prop ("red", "yellow", "green"). Use a lookup object to render the matching instruction text ("Stop", "Slow down", "Go") with a fallback of "Unknown signal" for any other value.

📄 View solution

Chapter 5 Quick Reference

  • No special JSX conditional syntax — it's all regular JavaScript
  • if/early return — entirely different JSX for different cases
  • Ternary — inline either/or, fits directly inside { }
  • && — render something or nothing; guard with an explicit comparison to avoid the 0 && ... trap
  • return null — the component renders nothing into the DOM at all
  • Lookup object + ?? — cleaner than chained ternaries for 3+ named states
  • Next chapter: lists and keys — rendering an array of data as repeated JSX