Most UIs show different content based on state — logged in vs out, loading vs loaded, empty vs populated. React uses JavaScript conditionals inside JSX to render UI selectively.
Conditional UI Patterns
Because JSX is JavaScript, you can use if/else, ternary operators (? :), logical AND (&&), and early returns to control what appears on screen.
Choose the pattern that keeps your JSX readable. Simple toggles suit ternaries; complex branching may be clearer with early returns or extracted helper components.
function Status({ isLoading, error, data }) {
if (isLoading) return <Spinner />;
if (error) return <ErrorMessage error={error} />;
if (!data) return <EmptyState />;
return <DataTable rows={data} />;
}
Early returns keep the happy path unindented and easy to read.
condition && <Component /> renders when condition is truthy.
Watch out: count && <Badge /> renders 0 when count is 0 — use count > 0 &&.
Ternary works well for either/or UI with two branches.
Extract complex conditions into named variables or subcomponents.
Conditional Rendering Cheat Sheet
Pick the right pattern for each situation.
Pattern
Best For
Early return
Mutually exclusive full-page states
Ternary
Two alternative UI blocks inline
&&
Show/hide a single element
Switch in helper
Many enum-based variants
Object map
variants[type] component lookup
Separate component
Complex conditional trees
Loading, Error, and Empty States
Data-driven UIs typically have four states: loading, error, empty, and success. Model these explicitly rather than nesting ternaries five levels deep.
function UserList() {
const { data, isLoading, error } = useUsers();
if (isLoading) return <Skeleton />;
if (error) return <Alert variant="error">{error.message}</Alert>;
if (data.length === 0) return <p>No users yet.</p>;
return <ul>{data.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}
Avoiding Nested Ternary Hell
Deeply nested ternaries are hard to read and maintain. Prefer early returns, lookup objects, or small child components named LoadingView, ErrorView, and SuccessView.
Common Mistakes
Using && with numeric zero, which renders "0" on screen.
Nesting too many ternaries in one JSX expression.
Not handling loading and error states for async data.
Putting side effects inside conditional JSX expressions.
Key Takeaways
Use JavaScript conditionals inside or before JSX returns.
Early returns clarify multi-state UIs.
Handle loading, error, empty, and success explicitly.
Extract complex branching into helper components.
Pro Tip
Name your UI states (loading, error, empty, ready) in comments or enums — it makes conditional logic self-documenting.
You can render UI conditionally in React. Next, learn lists and keys for dynamic collections.