Conditional rendering in React is great, here’s a tip to make sure you don’t get caught out by Javascript’s short-circuit evaluation.
It works!
Ever tried to use conditional rendering to hide a component in React when a variable or expression is falsy? I do it all the time, but sometimes Javascript’s short-circuit evaluation catches me out. Let’s have a look:
{ randomVariableOrExpression &&
<h1>Hello</h1>
}
The way we, or at least I, expect the above (and conditional rendering in general) to work is that if the variable/expression we evaluate is truthy, the component is rendered. And if it’s falsy, the component isn’t rendered.
Simple right?
We expect the behaviour I outlined above because it’s what happens 99% of the time. But there’s a catch.
Conditional rendering as outlined above functions because if the first value (randomVariableOrExpression) is falsy, the expression will short-circuit and simply return the falsy value.
React doesn’t render false
, null
, undefined
, or true
so nothing is rendered as expected, usually.
It Doesn’t Work?
However, if you were to write the below code where zeroVariable
evaluates to the number 0
, React will render 0 in your application.
{ zeroVariable &&
<h1>Hello</h1>
}
What? That’s not what you told it to do. You said, “If the value is falsy, render nothing”. This is where you either decide that React is broken and you’re the first one to notice (unlikely) or you’ve missed something.
What you’ve missed is that a logical expression which short-circuits is evaluated to the falsy value, not to false.
So in most cases, where the logical expression evaluates to false
, null
or undefined
you’ll see what you expect as React doesn’t render these values.
But there are values which are falsy that React does render, namely 0
, -0
and NaN
I first encountered this issue when I attempted to conditionally render some elements depending on whether an array was empty. My code was:
{ array.length &&
<div>
array.map((item, i) => (
<span>{ item }</span>
))
</div>
}
That looked right to me. If the array has any items in it then array.length
will be truthy and React will render my elements. If it’s empty then array.length
is 0
which is falsy and React won’t render anything.
As I’m testing my application, I see 0’s rendered everywhere.
“What the heck”, I thought.
I eventually figured out what I just explained to you. This doesn't only apply to array lengths. A variable could have a value of 0
or NaN
and unexpectedly render in your app.
Ohhh, It Works!!
As you may know, !
evaluates a value to true
or false
and inverts it.
!true == false
!false == true
!1 == false
!0 == true
Add a second !
and it’ll revert it to its original boolean value.
!!true == true
!!false == false
!!1 == true
!!0 == false
All you have to do is prepend your expression or variable with !!
(that's two exclamation points to be clear).
{ !!zeroVariable &&
<h1>Hello</h1>
}
This guarantees your falsy values (including 0
, -0
and NaN
) will resolve to false
(and be ignored by React) while keeping any truthy values as true
If you'd like to get in touch, can find me at frankpierce.me or email me at frank.pierceee@gmail.com
Top comments (1)
Awesome tip!