Beginner20 min read

Conditional Rendering

Learn how to render different UI elements based on conditions using ternary operators, logical AND, early returns, and more.

Why Conditional Rendering?

Real applications show different things depending on the situation — a login form when the user is not authenticated, a welcome message when they are, a loading spinner while data is being fetched, an error message when something goes wrong.

In React, conditional rendering means showing different elements or components based on some condition. Since JSX is just JavaScript expressions, you can use all of JavaScript's conditional logic to decide what to render.

There are several patterns for conditional rendering in React, each suited to different situations:

  1. Ternary operator — Choose between two alternatives
  2. Logical AND (&&) — Show something or nothing
  3. Early return — Skip the rest of the component
  4. Variable assignment — Prepare content before the return

Let's explore each of these patterns.

Ternary Operator: This or That

The ternary operator (condition ? ifTrue : ifFalse) is the most common way to conditionally render in JSX. It works directly inside curly braces and lets you choose between two pieces of JSX:

jsx
function LoginStatus({ isLoggedIn }) {
  return (
    <div>
      {isLoggedIn ? (
        <p>Welcome back, user!</p>
      ) : (
        <p>Please log in.</p>
      )}
    </div>
  );
}

You can use ternaries anywhere in JSX — for entire elements, for text content, for attributes, or for component props:

jsx
function Button({ isPrimary }) {
  return (
    <button 
      className={isPrimary ? 'btn-primary' : 'btn-secondary'}
    >
      {isPrimary ? 'Save' : 'Cancel'}
    </button>
  );
}

You can also nest ternaries, but this quickly becomes hard to read:

jsx
// Avoid deeply nested ternaries
{status === 'loading' ? (
  <Spinner />
) : status === 'error' ? (
  <Error />
) : (
  <Content />
)}

For more than two conditions, consider using early returns or a variable instead (covered in the next sections).

The ternary is best when you have exactly two alternatives and the logic is simple enough to read inline.

Logical AND: Show or Hide

When you want to show something or show nothing, the logical AND operator (&&) is cleaner than a ternary with null:

jsx
function Notification({ message, show }) {
  return (
    <div>
      <h1>Dashboard</h1>
      {show && <p className="notification">{message}</p>}
    </div>
  );
}

If show is true, React renders the <p> element. If show is false, React renders nothing.

This works because of how JavaScript's && operator evaluates:

  • true && <element> returns <element> (rendered)
  • false && <element> returns false (React ignores false, null, and undefined)

Watch out for the number zero! This is a common gotcha:

jsx
const count = 0;

// BUG: This renders "0" on screen, not nothing!
{count && <p>You have {count} items</p>}

Why? Because 0 && <element> returns 0, and React does render the number 0. The fix is to make the condition explicitly boolean:

jsx
// CORRECT: Convert to boolean first
{count > 0 && <p>You have {count} items</p>}

Use && when:

  • You want to show an element or nothing.
  • The condition is a boolean (or you have converted it to one).

The && pattern is perfect for optional UI elements like error messages, badges, tooltips, or conditional sections.

Early Returns and Variable Assignment

Early returns let you handle special cases at the top of your component before reaching the main rendering logic:

jsx
function UserProfile({ user }) {
  if (!user) {
    return <p>No user found.</p>;
  }

  if (user.isBanned) {
    return <p>This account has been suspended.</p>;
  }

  // Main rendering — only reached if user exists and is not banned
  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.bio}</p>
    </div>
  );
}

Early returns are great when a condition means the component should render something completely different. They keep the main rendering logic clean and unindented.

Variable assignment is useful when the conditional logic is too complex for inline ternaries:

jsx
function StatusMessage({ status }) {
  let content;

  if (status === 'loading') {
    content = <p>Loading...</p>;
  } else if (status === 'error') {
    content = <p>Something went wrong!</p>;
  } else if (status === 'empty') {
    content = <p>No data available.</p>;
  } else {
    content = <p>Here is your data.</p>;
  }

  return (
    <div className="status">
      <h2>Status</h2>
      {content}
    </div>
  );
}

You can also use a switch statement or even an object lookup for mapping values to components:

jsx
const icons = {
  success: <span>Success</span>,
  warning: <span>Warning</span>,
  error: <span>Error</span>,
};

function StatusIcon({ type }) {
  return icons[type] || <span>Unknown</span>;
}

Rendering null makes a component render nothing:

jsx
function Warning({ show, message }) {
  if (!show) return null;
  return <p className="warning">{message}</p>;
}

Returning null is a legitimate way to say "this component has nothing to display right now."

Conditional Rendering in Action

html
<div id="root"></div>
<script src="https://unpkg.com/react@19/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@19/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
  function App() {
    const [isLoggedIn, setIsLoggedIn] = React.useState(false);
    const [showDetails, setShowDetails] = React.useState(false);

    return (
      <div style={{ padding: "20px" }}>
        <h1>Conditional Rendering Demo</h1>
        
        {/* Ternary: show different content */}
        {isLoggedIn ? (
          <p>Welcome back, User!</p>
        ) : (
          <p>Please log in to continue.</p>
        )}
        
        {/* Ternary: different button text */}
        <button onClick={() => setIsLoggedIn(!isLoggedIn)}>
          {isLoggedIn ? "Log Out" : "Log In"}
        </button>
        
        <hr />
        
        {/* AND operator: show or hide */}
        <button onClick={() => setShowDetails(!showDetails)}>
          {showDetails ? "Hide" : "Show"} Details
        </button>
        {showDetails && (
          <div style={{ marginTop: "10px", padding: "10px", background: "#f0f0f0" }}>
            <p>Here are the extra details!</p>
            <p>They only appear when the button is toggled.</p>
          </div>
        )}
      </div>
    );
  }

  ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>

What does `{count && <p>Items: {count}</p>}` render when count is 0?

Ready to practice?

Create your free account to access the interactive code editor, run challenges, and track your progress.