Intro

So, you want to render something conditionally in React - easy, right? In React/JSX, there are several ways to write “render this component if this condition is true”. A common way relies on “short circuiting” via a logical AND operator (&&): the component will only be rendered if the left branch of the expression evaluates to a truthy value. If the left branch of the expression is falsy, the component is never mounted/rendered and the falsy value is ignored:

<View>
  {renderDialog && <Dialog />} // Dialog only rendered if renderDialog is truthy
</View>

The pitfall

If renderDialog evaluates to false, null, or undefined, everything works great! Our <Dialog> component won’t be rendered and React will ignore the evaluated value of renderDialog.

However, there are other possible falsy values in JavaScript- and these can wreck havoc in React Native!

Let’s imagine that <Dialog> has a required string prop, message. We only want to render <Dialog> if we have a message to show. We might write our JSX like this:

const dialogMessage = ... // some string, can be empty

return (<View>
  {/* ‼️ Danger - `dialogMessage` can be empty string! */}
  {dialogMessage && <Dialog message={dialogMessage}>} 
</View>)

If dialogMessage happened to be an empty string, the above will effectively be:

return (<View>{''}</View>)

In React Native, the above code will cause a dreaded red screen error - Text strings must be rendered within a <Text> component:

A React Native red screen error telling us that a text node must be in a Text component

Based on this error, we know that in React Native all text nodes must be children of the <Text> component. So, the empty string dialogMessage variable above is not a valid direct child of <View>.

This is more restrictive than React on the web, where a DOM Text node can be a child node of just about anything.

Alternatives & Prevention

Instead of using a logical AND operator with a possibly empty string, you can instead:

  • use !! to coerce the string to a boolean
  • use an old fashioned ternary operator

Both are safer alternatives to && and are just as easy to use:

<View>
  {!!renderDialog && <Dialog />}      // ✅ Use `!!` to convert to boolean 
  {renderDialog ? <Dialog /> : null}  // ✅ Use ternary
</View>

There’s also a great ESLint rule, eslint-plugin-jsx-expressions, to explore adding to your React Native projects.

This rule triggers if a string is used in a JSX expression. The rule comes with autofixes - making it painless to add to your projects. Perfect for preventing an accidental empty string outside of <Text> in React Native!

Further reading

Kent C. Dodds has a great post on some other reasons why you should avoid && in your components. Give that a read to learn about some other dangers of using && to conditionally render.