Why Is React Showing 0 When Conditionally Rendering a Component?

When using conditional rendering in React, sometimes you might get unexpected rendering of values such as 0, etc. This happens because React only skips rendering of anything that's a boolean, null or undefined. For example:

// these don't render anything
false && <RenderMe />
null && <RenderMe />
undefined && <RenderMe />

Since React skips the rendering of boolean, null or undefined they don't show up visibly in the render. However, they still exist as children and are included in the children array.

Keeping that in view, it is likely that the left-side variable in your short-circuit evaluation is returning a numeric or string "0". Although this is considered falsy in JavaScript, it would be rendered as is in React. For example:

0 && <RenderMe /> // renders: '0'
1 && <RenderMe /> // renders: <RenderMe />
true && <RenderMe /> // renders: <RenderMe />
'string' && <RenderMe /> // renders: <RenderMe />

As you can see from the examples above:

  1. When the left-side of the logical expression is truthy upon evaluation, the component renders because the whole expression short-circuit evaluates to true;
  2. When the left-side of the logical expression is false, it short-circuit evaluates to the falsy expression, and the falsy expression is rendered. However, when the left-side expression is boolean, null or undefined it won't render as React skips their rendering (as mentioned earlier).

How to Fix the Issue?

There are a couple of ways you can fix this issue; the main goal is to ensure that the left-side of the logical expression evaluates to; boolean, null or undefined when it's falsy. Considering that, you can do the following:

Convert the Left-Side Expression to Boolean:

To convert the left-side expression to boolean you can do any of the following:

  1. Evaluate the expression to a boolean by using comparison operators;
  2. Using the Boolean object (for example, Boolean(expression));
  3. Using double-negation (for example, !!(expression)).

The following examples shows how the above mentioned methods won't render anything when the left-hand expression is a falsy value (such as 0):

const expr = 0;

// using comparison operators
expr > 0 && <RenderMe />

// using Boolean object
Boolean(expr) && <RenderMe />

// using double-negation
!!expr && <RenderMe />

Use a Ternary Operator:

Instead of doing conditional rendering with short-circuit evaluation of logical && operator, you could perhaps try refactoring it into a ternary condition like so:

{condition ? <RenderMe /> : null}

Examples

"0" Renders on Short-Circuit Evaluation of Falsy Numeric Value:

In the following example, 0 is rendered because the short-circuit evaluation returns the falsy expression:

render() {
    const count = 0;

    return (
        <div>
            { count && <h1>Messages: {count}</h1> }
        </div>
    );
}

// renders: <div>0</div>

The example above is from the React docs.

Possible fix:

render() {
    const count = 0;
    return (
        <div>
            { count > 0 && <h1>Messages: {count}</h1> }
        </div>
    );
}

"0" Renders on Short-Circuit Evaluation of array.length && ...:

The following demonstrates a common problem when doing short-circuit evaluation of array.length && ...:

render() {
    const arr = [];

    return (
        <ul>
            { arr.length && arr.map((item) => `<li>${item}</li>`) }
        </ul>
    );
}

// renders: <div>0</div>

Possible fix:

render() {
    const arr = [];

    return (
        <ul>
            { arr.length > 0 && arr.map((item) => `<li>${item}</li>`) }
        </ul>
    );
}

You can of course use any other solutions described earlier to fix the issue.


This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.