Skip to Content
React in a Week
Day 2 · Describing the UI

Conditional rendering

Show different things depending on your data, using if, the ternary operator, && and null.

Not every book in your list should look the same. A book you've finished should say "Done", a book you're reading should say "Reading", and a rating should only appear if you've actually rated the book.

In React there is no special template language for this. You use the JavaScript you already know: if, the ternary operator and &&. This lesson shows where each one fits.

Using if to return different JSX

A component is a function, so it can run an if statement before it returns. Here StatusBadge returns a different <span> depending on its status prop:

Live code· if and early return

Each return ends the function, so only one branch ever runs. Use this style when the branches return quite different JSX, or when the logic is long enough that cramming it inside JSX would be hard to read.

Rendering nothing with null

Sometimes the right answer is "show nothing at all". A component can return null to render nothing:

function RatingLine({ rating }) {
  if (rating === undefined) {
    return null;
  }
  return <p>Rated {rating} out of 5</p>;
}

React treats null, undefined, false and true as "render nothing". That is what makes the shortcuts in the next section work.

Conditions inside JSX

An if statement can't go inside JSX, because JSX curly braces only accept expressions: pieces of code that produce a value. JavaScript has two expression-shaped tools for conditions.

The ternary operator: this or that

condition ? a : b means "if condition is true, use a, otherwise use b". It is handy when only a small part of the JSX changes:

<p>{book.status === 'done' ? 'Finished it!' : 'Not finished yet'}</p>

The && operator: this or nothing

condition && a means "if condition is true, use a, otherwise render nothing". Use it when there is no "else" branch:

{book.rating !== undefined && <p>Rated {book.rating} out of 5</p>}

Here are both in one component. Edit the books data to see the output change:

Live code· Ternary and &&

Try giving Dune a rating: 4, or changing The Hobbit's status to 'want'.

Live code· See the 0 bug for yourself
Quick check

What does this render when items is an empty array: {items.length && <List />}

Storing JSX in a variable

When a condition gets more complex, nested ternaries become hard to read. A tidy alternative is to work out the JSX in a variable first, using ordinary if statements, and then drop the variable into your JSX:

function BookCard({ book }) {
  let note = null;
  if (book.status === 'done' && book.rating >= 4) {
    note = <p className="note">A favorite!</p>;
  } else if (book.status === 'reading') {
    note = <p className="note">Keep going.</p>;
  }

  return (
    <article>
      <h2>{book.title}</h2>
      {note}
    </article>
  );
}

Another common trick is a lookup object. Instead of an if for every case, you map each possible value to what you want to show:

const statusLabels = {
  want: 'Want to read',
  reading: 'Reading',
  done: 'Done',
};

<span>{statusLabels[book.status]}</span>

The Reading List will use this pattern for its status badge.

Deep diveWhich style should I use?

All of these styles produce the same result, so pick the one that reads best:

  • Early return when a component either shows its normal output or something entirely different, such as an empty-state message.
  • Ternary for a small "this or that" inside JSX. Avoid nesting one ternary inside another.
  • && for a small "this or nothing". Make sure the left side is a real boolean.
  • A variable or a lookup object when there are three or more cases.

Readable code matters more than short code. If you have to squint at a condition, move it out of the JSX.

Try it

Finish the status badge

Complete BookCard so that:

  1. It shows a badge with the label "Want to read", "Reading" or "Done", using the class badge plus the status name (for example badge done).
  2. It shows "Rated N out of 5" only when the book has a rating.
  3. The rating line does not appear for a book with no rating field.
Live code· Challenge: badge
Show solution

A lookup object turns the status into a label, and a template literal builds the class name. The rating uses && with a real boolean on the left.

Live code· Solution: badge

An if chain inside a small StatusBadge component would also be a correct answer. You'll learn more about building class names like this in Styling components.

Quick check

Which of these values makes React render nothing on the screen?

Day 2 progress

0/7
Next: Rendering lists

On this page