Skip to content

Conditional Rendering

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.

Common Conditional Patterns

{isAdmin && <AdminPanel />}

{count > 0 ? <Badge count={count} /> : null}

{user ? <Dashboard user={user} /> : <LoginForm />}
  • 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.