Conditional Rendering Patterns
Pick the cleanest way to show, hide or switch between UI blocks.
Beyond the basics, a few patterns keep conditional UI readable as it grows.
Handy patterns
- Guard clause: return early for loading or empty states, then render the main case.
- Variable assignment: compute JSX into a variable with
if, then use it in the return. - Lookup object: map a status string to the component to render, avoiding long ternary chains.
Example
function View({ status, data }) {
if (status === 'loading') return <p>Loading...</p>;
if (status === 'error') return <p>Something went wrong.</p>;
if (data.length === 0) return <p>No results.</p>;
return (
<ul>{data.map((d) => <li key={d.id}>{d.name}</li>)}</ul>
);
}When to use it
- A dashboard uses a guard clause to return a loading skeleton early, keeping the main render path free of null-check noise.
- A notification feed stores the JSX for each notification type in a variable and renders it at one point in the return, avoiding repeated ternaries.
- A settings page uses an object map from setting type to component, replacing a long if-else chain with a one-liner lookup.
More examples
Guard clause early return
Returns early for loading and empty states so the main render path stays clean and readable.
function UserCard({ user, loading }) {
if (loading) return <Skeleton />;
if (!user) return <p>No user found.</p>;
return (
<div className="card">
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
}JSX stored in a variable
Assigns the type-specific icon to a variable before the return, keeping the JSX block uncluttered.
function Notification({ type, message }) {
let icon;
if (type === 'success') icon = <span className="icon-ok">β</span>;
else if (type === 'error') icon = <span className="icon-err">β</span>;
else icon = <span className="icon-info">βΉ</span>;
return (
<div className={`notification notification--${type}`}>
{icon}
<p>{message}</p>
</div>
);
}Component lookup map
Uses an object as a lookup table to select a component by variant, replacing a verbose if-else chain.
import AlertBanner from './AlertBanner';
import ToastMessage from './ToastMessage';
import InlineNote from './InlineNote';
const NOTICE_MAP = {
alert: AlertBanner,
toast: ToastMessage,
note: InlineNote,
};
function Notice({ variant, ...props }) {
const Component = NOTICE_MAP[variant] ?? InlineNote;
return <Component {...props} />;
}
Discussion