3 Anti-patterns for Conditional Rendering with React

You already know how to implement conditionally rendering with React: just use JavaScript! This gives you a huge amount of power... to shoot yourself in the foot.

21st September, 2018

Conditional rendering with React is just a matter of deciding which element object to return. You can use if and switch statements, the conditional operator, and even the && operator!

This gives you a lot of power — I’ll go into the details next week. The problem is that all of this power makes it easy to shoot yourself in the foot. Lucky for you, getting familiar with these 3 anti-patterns will help help you avoid most of the pain. I’ll start with the issue I run into most…

There’s something special about 0: it’s the only falsy value that JSX renders as text. This makes it generally a bad thing to guard on it.

For example, say you’re printing verses of “bottles of beer”, but you don’t want to print the last verse with “0” bottles of beer. You might attempt to handle this by prefixing the verse with bottlesOfBeer &&:

import React from'react'import ReactDOM from'react-dom'let bottlesOfBeer =0
ReactDOM.render(
bottlesOfBeer &&<h1>
Take one down and pass it around,&nbsp;{bottlesOfBeer} bottles of beer on the wall.</h1>,
document.getElementById('root'))

Oops! A random 0 appeared in your app.

One trick to avoid this is to coerce the left-hand side of your && operator into a boolean by using the !! operator. To see this in action, try removing the !! operator from the below example.

I run into this issue even after years of working with React. It’s easy mistake to make. But knowing why a random 0 has appeared in your app can turn minutes of debugging into seconds.

#I heard you like Conditional operators so I put a Conditional operator in your Conditional operator

One of the things about conditional operators, is that you can put them in other conditional operators. This is a little hard to explain, so the best way to see why this is a bad idea is to look at this example.

This hypothetical component will render a <Button> element, and will pass in different props depending on the value of props.status. The component will work; it’ll do exactly what it’s supposed to. But imagine that you don’t already know what it’s supposed to do, and you’re trying to figure it out… yuck.

Conditional operators are a great tool when used in moderation. Some people will tell you that you should never use a conditional operator inside another one. I’m a little more moderate, I think it depends on the situation. But try not to go overboard, or you might end up with a bit of a hangover.

The reason that conditional components don’t catch on is that they have some downsides that aren’t immediately obvious. In particular, unlike JavaScript’s if statement, their children will be evaluated regardless of whether the condition is met.

To understand why this is the case, let’s take a look at the above example in a live editor.

At first glance, this <Only> component seems to work great. So what’s the problem?

Let me start by asking you a question: what do you think will happen if you set user to null? Have a think about it, then try it out in the above editor to see for yourself.

Did you give it a shot? Then let’s continue!

The reason that setting user to null results in an error is that accessing user.name will throw an error if user is null. Remember, the children of <Only> are just arguments to a call to React.createElement(); they’ll be evaluated regardless of the value of the when prop! If you’re not convinced, click “compiled” and take a look.

In contrast, if you were to implement the same component using an && guard, then the <h1> tag will not be evaluated unless user has a value. Try confirming this for yourself by changing user to null in the example below:

Thanks so much for reading this far! Since you’re here, I have a question for you: Have you run into any other React footguns that I missed? Or is there anything else you’d like to hear more about? Let me know by tweeting @james_k_nelson!

Go Pro

Stay in the loop.

Keeping up to date with React is a full time job that pays only in frustration. Luckily, you can delegate! Just become a free member, and we'll keep you up to date with our monthly newsletter.