React Conditional Rendering
Render dynamic user interfaces using ternary operators, logical AND gates, early returns, and switch guards.
TL;DR
- Control rendered JSX output using standard JavaScript
ifbranch conditions. - Inline alternate elements inline with readable
?ternary conditional operators. - Gate single UI elements conditionally using
&&logical conjunction syntax.
Inline Conditional Syntax
Ternary OperatorChoose between two elements based on a boolean predicate.
return (
<View>
{isLoggedIn ? <Dashboard /> : <Login />}
</View>
);Logical AND GateRender element only when condition evaluates to true.
return (
<View>
{hasNotice && <Badge count={3} />}
</View>
);Safe Numeric GateCoerce count to boolean to avoid printing zero digits.
return (
<View>
{items.length > 0 && <ItemList items={items} />}
</View>
);Early Return Patterns
Loading Screen GuardReturn dedicated loading UI before accessing data.
if (isLoading) {
return <Spinner label="Fetching data..." />;
}Error Guard ReturnHalt normal rendering when an error is present.
if (error) {
return <Alert status="error" text={error.msg} />;
}Null GuardReturn null to render completely nothing in the DOM.
if (!shouldDisplay) {
return null;
}Multi-State Rendering
Dictionary MappingMap enum string keys to corresponding JSX elements.
const views: Record<string, JSX.Element> = {
home: <HomeTab />,
feed: <FeedTab />,
};
return views[currentTab] ?? <DefaultTab />;Switch StatementBranch across multiple states inside helper functions.
function renderStatus(status: Status) {
switch (status) {
case 'idle': return <StatusBadge text="Ready" />;
case 'busy': return <Spinner />;
case 'done': return <CheckMark />;
}
}Variable AssignmentAssign JSX to a local variable using conditional blocks.
let banner;
if (isHoliday) {
banner = <HolidayBanner />;
}
return <Layout>{banner}</Layout>;Conditional Styles and Classes
Template String ClassesToggle CSS class names conditionally using template literals.
<Button className={`btn ${isActive ? 'active' : ''}`}>
Toggle
</Button>Array Filter JoinAssemble class strings cleanly from filtered arrays.
const cls = [
'card',
isPrimary && 'primary',
isDisabled && 'disabled',
].filter(Boolean).join(' ');Conditional AttributesConditionally pass or omit optional JSX attributes.
<Button disabled={isSubmitting || !isValid}>
Submit
</Button>Tips
- Avoid using numbers directly on the left of
&&because zero values accidentally render in the DOM. - Extract complex multi-branch rendering logic into standalone subcomponents or clean
Recorddictionary maps for readability.
Warnings
- Never write
0 && <Tag />because JavaScript evaluates falsy zero into the visible digit0. - Avoid deeply nested ternary operators with multiple
?branches because they rapidly destroy component template readability.
In Practice
Demonstrate early return guards for loading, error, and empty states.
- Check for active loading status and return a progress spinner.
- Check for error states and render an alert message.
- Guard against empty record sets with helpful placeholder UI.
- Render the populated list only when valid data is present.
interface ViewProps {
isLoading: boolean;
error: Error | null;
products: string[];
}
export function CatalogView(props: ViewProps) {
if (props.isLoading) {
return <Spinner text="Loading..." />;
}
if (props.error) {
return <Alert text={props.error.message} />;
}
if (props.products.length === 0) {
return <EmptyNotice text="No products found." />;
}
return <ProductGrid items={props.products} />;
}FAQ
In JavaScript, 0 is falsy, but the logical AND operator returns the left expression when it evaluates to falsy. Use count > 0 &&
Return null from your component or JSX expression. React renders nothing to the DOM when encountering null, undefined, or false.
Use early returns when an entire component view changes based on a major condition, such as full-screen loading spinners, unauthorized access alerts, or fatal errors.