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:
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:
Try giving Dune a rating: 4, or changing The Hobbit's status to 'want'.
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
returnwhen 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.
Finish the status badge
Complete BookCard so that:
- It shows a badge with the label "Want to read", "Reading" or "Done", using the class
badgeplus the status name (for examplebadge done). - It shows "Rated N out of 5" only when the book has a rating.
- The rating line does not appear for a book with no
ratingfield.
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.
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.
Which of these values makes React render nothing on the screen?
Day 2 progress