Rather than hiding elements with CSS, React lets you decide with plain JavaScript whether an element should exist in the DOM at all. This lesson covers the full toolbox for that ā early returns, ternaries, the && operator, variable-based branching, and object maps ā along with the gotchas each one comes with.
1The React Way to Hide
Traditional web development often hides elements with CSS properties like display: none, but the element still exists in the DOM. React takes a different approach: JavaScript logic decides whether an element should exist in the rendered output at all.
When a condition is false, React simply bypasses that branch and never renders the corresponding HTML, rather than rendering it and then visually hiding it.
// Conditional Logic: To render or not to renderReact Component Preview
2The Early Return
The simplest, most readable way to handle a top-level condition is a standard if statement placed outside the JSX return block ā an Early Return. It's ideal for checks like whether a user is an admin or whether data is still loading.
When the condition is met, the component returns immediately and ignores all the code below it, so you never end up rendering logic meant for a different state.
function User({ isAdmin }) {
if (isAdmin) {
return <AdminPanel />;
}
return <GuestPanel />;
}React Component Preview
3Inline Ternaries
Standard if/else statements aren't valid inside a JSX tree, so choosing between two elements there calls for the JavaScript ternary operator ā condition ? <A /> : <B /> ā wrapped in curly braces. This is the industry-standard pattern for mutually exclusive UI, like showing a Login button when logged out and a Logout button when logged in.
Because it's an expression rather than a statement, a ternary can be dropped directly into the middle of JSX where a plain if statement never could.
<div>
{isLoggedIn ? <LogoutButton /> : <LoginButton />}
</div>React Component Preview
4The Logical AND (&&)
When there's only one element to render conditionally ā an if with no else ā the logical AND (&&) operator is the cleaner tool. React evaluates the left side first; if it's truthy, it renders the JSX on the right, and if it's falsy, it skips that JSX entirely.
This pattern is perfect for optional elements like a notification badge that should only appear {hasMessages && <NotificationDot />} when there's actually something to show.
<div>
{hasMessages && <NotificationDot />}
</div>React Component Preview
5Avoiding the Zero Trap
A common && bug involves the number 0. In JavaScript, 0 is falsy, so you might expect {items.length && <List />} to short-circuit and render nothing when the array is empty ā but React treats 0 as a valid text node and will actually print the literal character '0' onto the screen.
The fix is to make sure the left side of && always evaluates to a strict boolean, typically with a comparison like items.length > 0 && <List />.
// ā Renders '0'
{items.length && <List />}
// ā
Renders nothing
{items.length > 0 && <List />}React Component Preview
6Variable Based Logic
Once a condition has three or more possible UI states, ternaries become deeply nested and hard to read. The better pattern is to declare a variable, like let content;, before the return statement, then use standard if/else logic to assign the right JSX to it.
The final return statement then simply injects {content} into the tree, keeping the actual JSX clean regardless of how many branches the underlying logic has.
let content;
if (status === 'loading') content = <Spinner />;
else content = <Data />;
return <div>{content}</div>;React Component Preview
7Returning Null
Returning null from a component is an explicit instruction telling React's rendering engine to draw absolutely nothing to the DOM for that component. The component is still technically mounted in the tree ā it just produces no visible output.
This is exactly the pattern behind components like a Modal that stay mounted but invisible until a state flag like isOpen flips to true: if (!isOpen) return null;.
if (!isOpen) return null;
return <Modal />;(Empty Screen)
Modal returned null.
8The Object Map Pattern
For highly branched rendering, an alternative to long switch statements or chained if/else blocks is a JavaScript object map: an object whose keys match your possible state values and whose values are the corresponding JSX. You then look up the current state directly as a key, e.g. views[status].
This reads as a single, flat lookup rather than a cascade of conditionals, which scales much better as the number of possible states grows.
const views = {
loading: <Spin />,
error: <Err />,
data: <List />
};
return <div>{views[status]}</div>;React Component Preview
9Mastery Applied
Conditional logic isn't only for adding or removing whole elements ā it's just as commonly used to dynamically assign CSS classes. Injecting a ternary directly into a className string, e.g. ` className={btn ${isActive ? 'btn-active' : ''}} `, lets you toggle active states, error outlines, or theme colors instantly without duplicating markup.
This is the same branching logic from earlier applied to styling rather than structure, so it fits naturally alongside everything else covered in this lesson.
/* Mastered Conditional Logic */React Component Preview
10The Next Level
With early returns, ternaries, &&, variable-based branching, and object maps all in hand, you have the full toolkit for building intelligent, branching UIs ā the trick is picking the right one for how many states you're handling and how complex the logic is.
A single optional element calls for &&, two mutually exclusive options call for a ternary, and three or more states are usually clearer as a variable or an object map.
/* Ready for complex UI */React Component Preview
11Step-by-Step Breakdown
Conditional Logic. Welcome to Conditional Logic in React. In traditional web development, developers often 'hide' elements using CSS properties like display: none. In React, we take a different approach: we use JavaScript logic to determine whether an element should exist in the DOM at all. If a condition is false, React simply bypasses it and never renders the HTML.
Early Return. The simplest and most readable way to handle conditions is with a standard 'if' statement placed OUTSIDE of your JSX return block. This is called an Early Return. It is perfect for top-level checks, such as verifying if a user is an admin or if data is still loading. If the condition is met, the component returns early, ignoring all the code below it.
If you have complex loading logic that should stop the rest of the component from executing until data arrives, what is the best pattern?
- āMassive inline ternaries inside the JSX
- āAn Early Return before the main JSX
Ternary Operator. When you are inside a JSX tree, you cannot use standard 'if/else' statements. Instead, you use the JavaScript Ternary Operator (condition ? true : false) wrapped in curly braces. This is the industry standard for choosing between two mutually exclusive UI elements, such as showing a 'Login' button when logged out, and a 'Logout' button when logged in.
Inside a JSX tree, which operator is exclusively used for choosing between TWO different elements (an if-else replacement)?
- āThe Logical && Operator
- āThe Ternary ? : Operator
Logical AND (&&). If you only have one element that you want to render conditionally (an if without an else), you should use the Logical AND (&&) operator. React evaluates the condition on the left. If it is truthy, React renders the JSX on the right. If it is falsy, React skips the JSX entirely, effectively rendering nothing. This is perfect for optional elements like notification badges.
Which operator is best for rendering a <WarningBadge /> ONLY if a 'hasWarning' boolean is true, and rendering nothing otherwise?
- āTernary: hasWarning ? <WarningBadge />
- āLogical: hasWarning && <WarningBadge />
The Zero Trap. A very common bug with the && operator involves the number 0. In JavaScript, 0 is falsy, which means the && short-circuits. However, React treats the number 0 as a valid text node and will physically render '0' to the screen instead of rendering nothing! To fix this, always ensure the left side of && evaluates to a strict boolean, usually by using a comparison operator.
Variable Logic. When you have complex conditions with three or more possible UI states, ternary operators become deeply nested and unreadable. The best practice here is to declare a variable 'let content;' before your return statement. You then use standard if/else logic to assign the appropriate JSX to that variable, and simply inject {content} inside your final return tree.
If you need to evaluate 4 different possible states to determine what to render, what is the most readable approach?
- āUse a variable and standard if/else statements
- āChain 4 nested ternary operators together
Returning Null. In React, returning 'null' from a component is an explicit instruction to the rendering engine to completely ignore the component and draw absolutely nothing to the DOM. This is extremely useful for 'invisible' components like Modals that are technically mounted in the tree but shouldn't display anything until triggered by state.
If a component executes return null;, what does React physically inject into the DOM?
- āIt throws a syntax error
- āIt renders absolutely nothing
Object Maps. A highly advanced and clean pattern for conditional rendering is using a JavaScript Object Map. Instead of long switch statements or chained if-else blocks, you create an object where the keys match your state, and the values are the JSX components. You then simply look up the current state key in the object inside your return block.
Conditional Styling. Conditional logic isn't just for adding or removing entire elements; it is heavily used for dynamically assigning CSS classes. By injecting a ternary operator directly inside the className attribute string, you can toggle active states, error outlines, or theme colors instantly without writing redundant elements.
Mastery Achieved. Logic mastery achieved! You've learned to build intelligent, branching UIs. You know when to use Early Returns, how to leverage Ternaries and && operators safely, and how to utilize object maps for clean code. You are ready to build fully dynamic interfaces that respond instantly to user interactions and states.
Level Up š
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Conditionally Rendered Content Changes Should Be Announced
When a condition swaps in an error message, a badge, or newly revealed content, wrap the region in `aria-live` (or move focus to it) so screen reader users learn about the change instead of only sighted users noticing the visual difference.
<div aria-live="assertive">{error && <p>{error}</p>}</div>2A Component That Returns null Must Not Leave Dangling ARIA References
If another element points at a conditionally-rendered component via `aria-labelledby` or `aria-describedby`, make sure that reference is also removed or updated when the component returns `null` ā a reference to a nonexistent id will silently fail to announce anything.
SEO Implications
- 1
Content Hidden Behind a Conditional That Defaults to False Won't Be Indexed
If SEO-relevant content is gated behind a condition that starts `false` and only becomes `true` after client-side interaction (like clicking to expand a section), a crawler evaluating the initial render may never see it ā render important content by default when possible.
- 2
Returning null for Loading or Error States Should Be Temporary and Fast
A component that returns `null` while data is loading briefly shows nothing to a crawler snapshot at that moment; keep such states short-lived and prefer server-rendering the real content when the data is available at request time.
Best Practices
Pick the Simplest Branching Tool for the Number of States Involved
Use `&&` for a single optional element, a ternary for two mutually exclusive options, and a variable or object map once there are three or more ā reaching for nested ternaries past two branches quickly becomes unreadable.
Always Coerce Numeric Conditions to a Strict Boolean Before &&
Write `items.length > 0 && <List />` instead of `items.length && <List />` ā the latter renders a literal '0' on screen when the array is empty, since React treats `0` as valid renderable text rather than 'nothing'.
Frequent Bugs
A component unexpectedly renders the number '0' on screen when a list or count is empty.
The left side of a `&&` expression evaluated to the falsy number `0`, and React renders `0` as text instead of treating it like `false`. Force a strict boolean with a comparison, e.g. `count > 0 && <Badge />`.
Deeply nested ternary operators inside JSX become unreadable and hard to debug.
Once there are three or more possible rendering branches, replace the nested ternaries with a variable assigned via `if/else` before the return, or with an object map keyed by the state value.
Real-World Examples
Status-Driven Rendering With an Object Map
A data-fetching component has three possible states ā loading, error, and success ā and looks up the JSX to render directly from an object keyed by the current status, avoiding a chain of if/else statements.
const views = {
loading: <Spinner />,
error: <ErrorMessage />,
success: <DataList />
};
return <div>{views[status]}</div>;