Search IOCombats

Search challenges, guides, questions and articles

What Is Conditional Rendering in React?

Beginner8 min interview
Skills tested:
Understanding that conditional rendering in React is just JavaScript control flow in JSXUsing if/else with early return for loading and error guard clausesUsing ternary for two-branch inline conditionsUsing logical AND for "render if true, nothing if false"Knowing the falsy 0 bug with && and how to fix it

Advertisement

🧩 Scenario

Conditional rendering appears in every React component: loading states, error boundaries, role-gated UI, empty states, and feature flags. React does not have template directives like v-if or *ngIf. It uses JavaScript expressions directly in JSX, which means the same control flow you already know determines what renders.

Architecture Walkthrough

Why React Has No Template Directives

React chose JavaScript over template syntax intentionally. JSX compiles to React.createElement calls, and inside any JSX expression you can use any JavaScript expression that returns a renderable value: a string, a number, a React element, an array of elements, null, or undefined. This means all JavaScript control flow tools (if/else, ternary, logical operators) work directly, with no new syntax to learn.

The constraint is that JSX curly braces accept expressions, not statements. {if (...) {...}} is invalid because if is a statement. Ternary (? :) and logical operators (&&, ||) work because they are expressions that produce values.

Guard Clauses with Early Return

The most readable pattern for loading, error, and unauthorized states is an if statement with an early return before the main return. Each condition returns immediately and the main return handles the success path. This keeps the primary render clean with no nesting.

This pattern is called a guard clause. It is especially readable when there are three or more early exits, because each is a flat, unconditional return at the top of the function, making the happy path obvious at a glance.

Ternary and Logical AND

Ternary handles two-branch conditions inline: {isLoading ? <Spinner /> : <Content />}. It explicitly handles both the true and false case. For "show this or nothing," && is the shorthand: {isLoggedIn && <UserMenu />}.

The critical && gotcha: if the left operand is a falsy number like 0, React renders it as text. {items.length && <List />} renders 0 when the array is empty. Fix it with a boolean conversion: {items.length > 0 && <List />}.


Key Code Explained

// Pattern 1: if/else with early return — guard clauses
function UserProfile({ userId }: { userId: string }) {
  const { data: user, isLoading, error } = useUser(userId);

  if (isLoading) return <Skeleton />;
  if (error) return <ErrorMessage error={error} />;
  if (!user) return null;

  // Main return: success path — no nesting, no ternary
  return (
    <div className="profile">
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  );
}


// Pattern 2: ternary — two branches inline in JSX
function AuthButton({ isLoggedIn }: { isLoggedIn: boolean }) {
  return (
    <button onClick={isLoggedIn ? logout : login}>
      {isLoggedIn ? 'Sign Out' : 'Sign In'}
    </button>
  );
}


// Pattern 3: logical AND — "render if true, nothing if false"
function Notification({ count }: { count: number }) {
  return (
    <div className="icon-wrapper">
      <BellIcon />
      {/* BUG: renders literal "0" when count is 0 */}
      {count && <span className="badge">{count}</span>}

      {/* CORRECT: convert to boolean first */}
      {count > 0 && <span className="badge">{count}</span>}
    </div>
  );
}


// Pattern 4: return null — component contributes nothing to the DOM
function AdminBadge({ role }: { role: string }) {
  if (role !== 'ADMIN') return null;

  return (
    <span className="badge badge-admin">Admin</span>
  );
}


// Real-world: composing all four patterns
function Dashboard({ userId }: { userId: string }) {
  const { data, isLoading, error } = useDashboard(userId);
  const { isAdmin } = useUserSession();

  if (isLoading) return <DashboardSkeleton />;  // guard clause
  if (error) return <ErrorMessage error={error} />;  // guard clause

  return (
    <div>
      <header>
        <h1>{data.greeting}</h1>
        {isAdmin && <AdminBadge role="ADMIN" />}  {/* && for boolean-gated UI */}
      </header>
      <main>
        {data.items.length > 0  {/* ternary for list vs empty state */}
          ? <ItemList items={data.items} />
          : <EmptyState />
        }
      </main>
    </div>
  );
}

Guard clauses handle loading and error at the top because these are not binary choices: they are exits. Ternary handles the list-vs-empty choice inside the return because both branches produce meaningful UI. Logical AND handles the admin badge because showing nothing when not admin is the correct silent behavior.


Tradeoffs

PatternBranchesWhere it livesBest for
if/else + early return2+ flatBefore returnLoading, error, unauthorized guard clauses
Ternary (? :)Exactly 2Inside JSX Binary inline conditions
Logical AND (&&)1 (true)Inside JSX "Show this or nothing" — watch for falsy 0
return null1 (false)Inside component bodyComponent should not exist in the DOM

What Interviewers Actually Check

  • Whether you know all four patterns and can choose the right one for the situation
  • Whether you know the falsy 0 bug with && and can fix it
  • Whether you know that returning null is how to render nothing
  • Whether you avoid nested ternaries for three or more branches
  • Whether you know why if statements cannot go inside JSX {} (statements vs expressions)

Follow-Up Questions

  1. Why does {items.length && <List />} render 0 when items is empty, and why does {Boolean(items.length) && <List />} not?
  2. How would you conditionally render a component only on the server in Next.js App Router?
  3. What is the ?? (nullish coalescing) operator and when is it useful for conditional rendering compared to ||?
  4. Can you use a switch statement for conditional rendering? If not directly in JSX, how do you achieve it?
  5. How does React.lazy and Suspense relate to conditional rendering for code-split components?

Common Candidate Mistakes

  • Writing {count && <Badge count={count} />} and not knowing it renders 0 in the DOM when count is 0
  • Using deeply nested ternaries for three or more conditions when if/else before return is cleaner
  • Not knowing that returning null is valid and removes the component from the DOM entirely
  • Trying to use if statements directly inside JSX {} and being surprised it does not work
  • Reaching for CSS display: none when the component should not be mounted at all

Interview Readiness Checklist

Before you leave this question, make sure you can answer:

  • Can you use if/else with early return for guard clauses before the main return?
  • Can you use ternary for two-branch inline conditions inside JSX?
  • Can you use && correctly and explain the falsy 0 bug and its fix?
  • Can you return null to render nothing and explain when to prefer it over && in the parent?
  • Can you explain why if statements are not allowed inside JSX {} but ternary and && are?

Summary

Conditional rendering in React is plain JavaScript control flow applied to JSX. React has no template directives; instead, any JavaScript expression that returns a renderable value can appear inside JSX curly braces. This means ternary, logical operators, and values from if/else assigned to variables all work directly.

The four patterns cover all cases. Guard clauses (if/return before the main return) handle loading, error, and unauthorized states flatly with no nesting. Ternary handles two-branch inline conditions inside JSX. Logical AND (&&) handles "show if true or nothing" with the critical caveat that falsy numbers like 0 render as text: always convert to a boolean before the &&. Returning null from a component renders nothing and removes the component from the DOM entirely, unlike CSS visibility which keeps the component mounted.

The most common interview mistake is the falsy 0 bug: {count && <Badge />} renders the number 0 when count is 0. The fix is {count > 0 && <Badge />}. The second most common is nested ternaries for three or more branches, which is a readability problem solved by if/else before the return statement.

Frequently Asked Questions

Does React have a built-in conditional rendering directive like v-if or *ngIf?

No. React uses plain JavaScript expressions inside JSX. There is no template syntax — just if/else, ternary, and logical operators applied to JSX values.

Advertisement


Stay Updated

Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.

Namaste React
Sponsored

A structured, project-based React course built for interviews.

View Course

Advertisement