Conditional rendering in React (jsx)

My findings…

Kawere Wagaba
Nerd For Tech
4 min readJul 20, 2021

--

Handling file input

Basically the condition has to evaluate to true or false. This is different from how conditionals work in js. Here’s what i mean:

data.length > 0 && <div />

The component is only rendered if the condition on the left evaluates to true. But coming from pure js, > 0 is redundant so I expect the following line to work:

data.length && <div />

Turns out that line won’t work, (as expected) why —

In the first case, if the size of the array is 0, 0 > 0 will evaluate to false so false && [anything really] evaluates to false, so the component won’t be rendered.

In the second, however, if the size is 0, 0 && <div /> evaluates to 0<div />. In other words, both 0 and the element will be rendered. Coming from js I’d expect the && operator to coerce 0 on the left side to a boolean (false) but that doesn’t happen, so they both get rendered — it’s how jsx works?

You would expect the statement 0 && <div /> to evaluate to false. That would actually be the case outside jsx.

const value = data.length ? 1 : 0;

The above statement assigns value a 1 if the size is greater than 0, and a 0 otherwise — which I find very deterministic than the jsx counterpart. i understand coercing a negative returns true, but length can’t be -ve — I could be wrong.

How about the below statement, what do you think the result would be?

data.length ? <div />: <err />;

That’s where it gets confusing. This tends to contradict what we discussed earlier. It actually works as it would, in normal js.

So guess it boils down to how the binary (&&)and ternary (? :)operators handle conditionals in jsx — one coerces (ternary) and the other does not (binary).

How about if we switched around the operands of the binary operator

<div /> && data.length > 0

This can be a gotcha for most beginners. What happens is the component will be rendered regardless the evaluation on the right! Weird, right?

I’ve know people that stay away from the binary operator in jsx altogether due to its non deterministic nature. They use the ternary and provide null as the operand when they want nothing rendered for a particular evaluation.

I’ve also found the above rules to work the same for dynamic classNames.

Let’s say u have a component that indicates the current step in a process, and u want to give that a different colour/behaviour — extending the styles for all step components.

What I mean…
<div className={`step ${current ? 'current' : ''}`} />

When u examine the component, in dev tools, the above approach creates a second class (which appears as extra space) in the DOM for components that are not current. If there was a space selector (maybe there is — i don’t know) that could lead to name conflicts.

How about using the null operand for the false evaluation?

<div className={`step ${current ? 'current' : null}`} />

Well, u guessed right — that adds null to the list of space-separated class names for the rest of the elements. More chaos.

How about going binary? Well, let’s see…

<div className={`step ${current && 'current'}`} />

Turns out that seemingly elegant solution, too works, but same problem as above — you get false as a class name to non-current items.

My favourite is still the empty string '' for the false evaluation. Let me know the technique you deploy.

If the way you’ve designed your component you won’t be inheriting any styles, like I’m doing above (where all current and non current components have a parent class of step) — and are probably willing to duplicate some of the rules (what’s the damage) then the problem can become much easier:

<div className={current ? 'current' : 'not-current'} />

So the components take entirely different classes depending on their state. That may require duplicating a couple of rules but it seems to solve the previous problem. The challenge is keeping the two classes in sync!

Still, my fav is the ''.

--

--