Don't evaluate JSX expressions with zero in React
When writing conditional JSX expressions in React, don't use the number 0
to evaluate those expressions. The results might surprise you.
Let's take a look at an example that conditionally shows a list of products. If there is at least one item in the products
array, then the Products
component should be rendered. If not, nothing should be rendered to the screen.
import { useState } from 'react';
import Products from './Products';
function App() {
const [products, setProducts] = useState<string[]>([]);
return (
<div>
{products.length && <Products products={products} />}
</div>
);
}
export default App;
The App
component above will render 0
to the screen. It is equivalent to writing the following in the App
component.
function App() {
return (
<div>
{0}
</div>
);
}
The 0
is rendered because products.length
evaluates to 0
. The number 0
is a falsy value in JavaScript. Therefore, the JavaScript logical AND operator &&
stops and and returns the original value of that falsy operand, which is 0
.
The number 0
is a valid value in JSX, unlike other falsy values such as an empty string, null
, undefined
, or false
. Therefore, 0
gets rendered to the screen.
To fix this, the JSX expression that checks the length of the products
array needs to evaluate to a boolean value of either true
or false
. Let's update the App
component accordingly.
import { useState } from 'react';
import Products from './Products';
function App() {
const [products, setProducts] = useState<string[]>([]);
return (
<div>
{products.length > 0 && (
<Products products={products} />
)}
</div>
);
}
export default App;
The expression products.length > 0
will always evaluate to either true
or false
. If it evaluates to true
, the list of products will be displayed. If it evaluates to false
, the list of products will not be displayed.
With this change, we'll no longer run into the issue where the numeric value for the products
array length is rendered to the screen.