Conditional Rendering
If you have some experience with React, you have seen conditional rendering.
Here we use ||
and &&
. If you're thinking "Boring, I can predict what happens." you might be right. But unless you can explain why Kyle Simpson calls ||
and &&
"operand selector operators", you probably don't understand what's really going on here. The weird thing about operand selector operators is that you can use them without understanding them and they still do the correct thing most of the time. Watch out for when they don't!
What threw me off, is that I had an adjacent case using &&
, where renderChildren
was 0
. To my surprise, the 0
got rendered, even though it's falsy. But when children
was 0
and ||
was used, nothing was rendered even though renderChildren
was true
.
Let's have a little test. What is being returned here?
Easy enough, right?
What about this?
Did you guess this?
Wrong. ||
and &&
do not return boolean values (unless you use them with true
or false
as in example one).
What's really being returned is this.
This means ||
and &&
return one of their operands - they "select" one, hence the name operand selector operators.
||
checks if the first operand is truthy using ToBoolean
. If yes it returns the first operand, otherwise the second.
&&
works the exact opposite way. If its first operand is truthy, it returns the second, otherwise the first.
If you use operand selector operators in an if
statement, for example, they only work as you expect because of implicit type coercion. The if
statement also invokes ToBoolean
on the primitive inside its brackets.
We also have to know which primitives React renders to understand conditional rendering.
If you try this code out in a CodeSandbox, you will see that only 0
, 1
, NaN
and "foo"
get rendered. This is also true for the value in the array. So the code above will render 01NaNfoo01foo
.
What's interesting to note here is that React doesn't go by whether a value is truthy or falsy to determine what should be rendered. If that where the case, true
would've gotten rendered, but 0
and NaN
not.
Test yourself: What is being rendered?
Knowing how React renders primitives, and understanding ||
and &&
it's clear to you now, why and when 0
gets rendered if you use it as renderChildren
or children
. Only Test 3 and Test 4 render nothing.
More Quirks
Another gotcha with ||
and &&
is operator precedence. From mathematics you might know that *
is always evaluated before any +
.
Similarly, &&
is always evaluated before ||
if there are no explicit brackets.
Additionally, you also should know that the operand selector operators short circuit.
In the first example, only foo
is evaluated. In the second, both bar
and foo
are invoked because bar
returns false
, which is obviously falsy
.
Aside from conditionally rendering React components, you can use &&
to conditionally assign an optional key to an object using the spread syntax.
Why use &&
here? Without &&
, name
would explicitly be undefined
when getName
is called with anon
.