Conditional Rendering
UIs change with data: show a spinner while loading, an error if something failed, a “Sold out” badge when stock is zero. React uses plain JavaScript to decide what to render.
On this page · 5 min · Beginner
On this page
- Learning objectives
- Explanation
- Syntax
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Beginner
- Updated
- Oct 28, 2026
Related tutorials
Learning objectives#
- Choose between elements with if, ternary and &&
- Return null to render nothing
- Avoid the “0 on screen” bug with &&
- Keep complex conditions readable
Explanation#
Before return, use normal if statements and early returns: if (loading) return <Spinner />;.
Inside JSX, choose between two options with a ternary: {isOpen ? <Menu /> : <MenuButton />}.
Show something or nothing with &&: {error && <p>{error}</p>}.
Watch out: {count && <Badge />} renders 0 when count is 0, because 0 is falsy but still rendered. Use {count > 0 && <Badge />}.
Returning null from a component renders nothing. For many cases, a variable set before return or an object lookup ({ success: <Ok />, error: <Fail /> }[status]) keeps JSX readable.
Syntax#
if (loading) return <p>Loading…</p>;
return (
<>
{user ? <p>Hi {user.name}</p> : <button>Log in</button>}
{items.length > 0 && <Cart items={items} />}
</>
);
Code example: Order status in four states#
function StockBadge({ stock }) {
if (stock > 10) return null; // nothing to show
return <span>{stock === 0 ? 'Sold out' : `Only ${stock} left`}</span>;
}
function OrderStatus({ status, order, error }) {
if (status === 'loading') return <p>Loading order…</p>; // early return
if (status === 'error') return <p role="alert">Error: {error}</p>;
return (
<article>
<h3>Order #{order.id}</h3>
{order.items.length > 0 && <p>{order.items.length} items</p>}
{order.items.length === 0 && <p>No items</p>}
{order.delivered ? <p>Delivered ✓</p> : <p>On the way 🚚</p>}
<StockBadge stock={order.stock} />
</article>
);
}
export default function Demo() {
return (
<>
<OrderStatus status="loading" />
<OrderStatus status="error" error="Network down" />
<OrderStatus status="ok" order={{ id: 7, items: [], delivered: false, stock: 0 }} />
<OrderStatus status="ok" order={{ id: 8, items: ['Pen', 'Bag'], delivered: true, stock: 40 }} />
</>
);
}
Loading order… Error: Network down Order #7 — No items — On the way 🚚 — Sold out Order #8 — 2 items — Delivered ✓ (no stock badge: stock is 40)
This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.
Step-by-step explanation#
- Early returns handle loading and error before any order data is read.
- items.length > 0 && ... avoids printing a stray 0 for empty orders.
- A ternary switches between “Delivered” and “On the way”.
- StockBadge returns null when stock is high, so nothing is rendered.
Real-world use case#
Every data screen has the same shape: if loading show a skeleton, if error show a retry button, if empty show “No orders yet”, otherwise show the table.
Common mistakes#
{items.length && <List />} shows “0” for an empty list. Compare explicitly: items.length > 0 && ...
a ? b : c ? d : e is hard to read. Use early returns or a lookup object.
order.items.length crashes while order is undefined. Handle loading first.
Best practices#
- Early returns for loading/error/empty
- Ternary for either-or, && for show-or-nothing
- Explicit boolean conditions with &&
- Return null to hide a component
Remember this#
Either/or → ternary. Maybe → &&. Nothing → null.
{count > 0 && …}, never {count && …}.
Handle loading and error first.
Practice exercise#
Your task: Write a Greeting component: if user is null show a "Log in" button; if user.isAdmin show "Welcome back, admin <name>"; otherwise "Welcome back, <name>".
Need a hint?
Show solution
export default function Greeting({ user = { name: 'Asha', isAdmin: true } }) {
if (!user) return <button>Log in</button>;
return <p>Welcome back, {user.isAdmin ? `admin ${user.name}` : user.name}</p>;
}
Mini quiz#
messages is an empty array. What appears on screen?
<div>{messages.length && <Inbox />}</div>
Want more? Practise all React MCQs · React interview questions
My notes#
Saved in this browser.