Javascript Conditionals vs ReactJS Conditional Rendering
ReactJS has this really nice feature built into it called conditional rendering. Essentially, this gives the ability for users to specify whether or not a component is rendered to the screen based on some condition. For example, say I have a component composed of 3 <div>
s
that would result in a render like
Now, if I wanted to render the green <div>
based on a boolean value, I could do something like
resulting in
Pretty simple right? If shouldRenderGreen
is true
, the green <div>
will render, otherwise it will not.
Now, as a Javascript developer, you’re probably familiar with some of the “inconsistencies” that come with conditionals. Many of these having to do with the type coercion that occurs when using a loose comparison (such as ==
) as opposed to a strict comparison (i.e. ===
).
However, this type coercion can sometimes be used to your advantage. If you want to check to see if a value is null
or undefined
, all you have to do is check x == null
, and that will check both cases. Nice!
This can also be useful for comparing number
values to numbers stored in strings (to prevent floating point issues). Things like1 >= ‘1.000001’
for instance.
Heres where things get interesting.
So what happens if I try to render my components based off of these loose comparisons? I’m going to focus on the values of ''
, []
, and 0
. In Javascript, these values are all loosely equal to false
, meaning that
'' == [] == 0 == false
.
Here are the results of our conditional rendering from these 3 values:
<div className="App">
<div className='red block' />
{'' &&
<div className='green block'/>
}
<div className='blue block' />
</div>
<div className="App">
<div className='red block' />
{[] &&
<div className='green block'/>
}
<div className='blue block' />
</div>
And weirdest of all:
<div className="App">
<div className='red block' />
{0 &&
<div className='green block'/>
}
<div className='blue block' />
</div>
Whats the deal? Aren’t these all equal? Not necessarily. When coercing the empty array []
to a boolean value, we see that !![] === true
whereas for the other 2 values !!0 === !!'' === false
. This explains why the empty array renders the green block while the other 2 values do not. Ok, fine, what about the 0 condition? In JS, 0 is considered a “falsy” value, meaning that when it is evaluated by &&
, it will return 0. Then, since 0 is not a true boolean value, it is rendered to the screen.
'' && <MyComponent/> //evaluates to '' which renders nothing
0 && <MyComponent/> //evaluates to 0 which renders 0
[] && <MyComponent/> //evaluates to <MyComponent/>
Takeaways:
- Be careful with your type usage. Javascript will come back to haunt you if you are not.
- Try to use strict equality as much as you can, I use it exclusively other than the
null|undefined
check. - If rendering conditionally, cast your value to a boolean beforehand. Changing the
0 && <MyComponent/>
to!!0 && <MyComponent/>
works as you’d expect.