React Native – How To Make Conditional Rendering Safer In React Native ?

Hello Readers, CoolMonkTechie heartily welcomes you in this article (How To Make Conditional Rendering Safer In React Native ?).

In this article, We will learn how to use conditional rendering safer in react native. Sometimes, depending on the conditions, we need to perform various actions or present the particular view. To do this, we will use the conditional statements.

Very soon after start of creating first app every developer needs to render component in one way or another depending on props. When one start searching, the first answer is inside React documentation. The answer is “Conditional Rendering”. But after a while many of us starts facing errors in React Native (or wrong rendering in React for web) that seems to jump on occasionally to reappear some time later. This article will explain what is happening and how to prevent further mistakes.

A famous quote about learning is :

” That is what learning is. You suddenly understand something you’ve understood all your life, but in a new way.”

So Let’s begin.


Conditional Rendering

Conditional rendering using inline If with logical && (AND) operator as React docs says:

You may embed any expressions in JSX by wrapping them in curly braces. This includes the JavaScript logical && operator. It can be handy for conditionally including an element — React docs: Conditional Rendering


Example 1Text Example

{someValue && (
  <View style={styles.field}>
    <Text>{someValue}</Text>
  </View>
)}

This handy solution is used by many and it’s nothing new for our community to see in the code. How and why it can crash your React Native app?

When using it widely in our App without proper attention sooner or later we will see this error (or worse scenario our users will see that the app crashed):

Invariant Violation: Text strings must be rendered within a <Text> component.

Then we see such an error in our logs and scratch our head because usually it works, it may crash for one particular data entry or after some small API change. What happened? Hint: someValue type matters.


Example 2 – Array Example

Another common example of javascript operator wrong usage is rendering something is array contains any elements:

// Sooner or later this code will surprise users.
// Just wait for an empty array.
{dataEntries.length && (
  <View>
    <Text>Visible only when array is not empty</Text>
  </View>
)}

Above example looks fine at a first glance. Array’s length will be 0 which is falsy thus condition is not satisfied and following component is not rendered — simple. This reasoning is partially good but author might forgot about one little fact that will surprise users at some point. Let’s take a closer look.


How logical AND && operator in JavaScript works?

Let’s see the docs again:

OperatorSyntaxDescription
Logical AND (&&)expr1 && expr2If expr1 can be converted to true, returns expr2; else, returns expr1.

If a value can be converted to true, the value is so-called truthy. If a value can be converted to false, the value is so-called falsy.

Examples of expressions that can be converted to false are:

  • null;
  • NaN;
  • 0;
  • empty string ("" or '' or ``);
  • undefined.


String Variable

Boolean('hello world')
// -> true

Boolean('')
// -> false

Boolean(' ')	// space
// -> true

'' && 'conditionally returned string'
// -> ''

'hello world' && 'conditionally returned string'
// -> 'conditionally returned string'

Empty string is falsy so AND operator will return '' because the condition is not fulfilled. Returning '' directly into ReactNative JSX will produce error Text strings must be rendered within a <Text> component and cause crash.


Numeric Variable

Boolean(-1)
// -> true

Boolean(0)
// -> false

Boolean(1)
// -> true

0 && 'conditionally returned string'
// -> 0

1 && 'conditionally returned string'
// -> 'conditionally returned string'

Zero is falsy so logical AND operator will return 0 as the condition is not met. Returning 0 into ReactNative JSX will cause crash with Invariant Violation error again.


Other Variable Types

Boolean(null)
// -> false

Boolean(undefined)
// -> false

Boolean({})
// -> true

Boolean([])		// worth noting!
// -> true

From the above examples the most interesting from React Native developer’s point of view is array. Usually when we put array into conditional render we would like not to render anything if array is empty. Passing an empty array into logical expression without any preparation will mislead us. What one would need to do is to check whether length exists and is equal to 0.


Why React Native crashes?

Rendering string in React Native must be wrapped with <Text>...</Text> component. But when we want to hide entire component when variable is empty with conditional rendering it may return an empty string directly into JSX. For example:

let optionalStr = ''

// [...] some logic that leaves `optionalStr` empty

{optionalStr && <Text>{optionalStr}</Text>} // crash

Now we know that above condition is not fulfilled therefore logical AND operator will return optionalStr directly into main JSX.


What about a numeric variable?

Normally, JavaScript expressions inserted in JSX will evaluate to a string, a React element, or a list of those things. […] — React docs: JSX in Depth

React tries to convert results of our expressions into a string, React element or array. This is why we see Invariant Violation: Text strings must be rendered within a <Text> component even if our variable was Number. It may be misleading while searching for this bug in a production code.


Why Is It Hard To Find React Native Conditional Render Error?

This error is sneaky because it may take a long time before it shows up. Our code may be working like a charm without any issues for months and suddenly something changes on API and type of that nullable variable changes suddenly to empty string or 0.

Why it works with variables that are null or undefined then? It will also work for booleans. React creators make our life easier and by default such variables are ignored in a JSX tree. It is special case and it will not be rendered.

React will also not crash when we put empty array directly into JSX as arrays can render multiple elements.

// below expressions will not crash your React Native app
<View>
  {false}
  {true}
  {null}
  {undefined}
  {[]}
</View>


Different Options To Make Conditional Rendering Safer

We just make sure to convert every variable into Boolean before using logical AND && operator.

We can do it multiple ways:

  • Double negation — !!dangerousData
  • Classic conversion — Boolean(dangerousData)
  • Rethink components architecture


1. Double negation — !!dangerousData

It’s an easy quick fix that will work and some experiments says that it’s execution time is faster than Boolean(dangerousData). We do not recommend it though.

This solution’s main pitfall is a human factor. Someone in our team could think that it is pointless to do double negation as it goes from true -> false -> true. It may lead to “refactor” that will create potential crashes in the future as this error may not reveal itself at first. My number one principle while coding is readability.


2. Classic conversion — Boolean(dangerousData)

This seems readable but as we mentioned above some say that it is slower in execution time so make our own research and decide if it is OK for our particular case. We can find news that in modern browsers it is optimized. We may also use some transpilers to change it before it goes to final code.


3. Rethink components architecture

Maybe we don’t need as many conditional renders in the component. Every component should be small and have simplified logic as much as it can. We have seen many overly complicated components with nested conditional renders and believe me it’s not something easy to maintain as our code grows.


3.1. Use Element Variable

In simple components sometimes we can use trick from React documentation with if and variable assignment preceding return.

// ...
  let message = <Text>'Hello there!'</Text>
  if (isVillain) {
    message = <Text style={styles.deepVoice}>'General React'oni!'</Text>
  }

  return <View>{message}</View>


3.2. Component Is A Function (IF ELSE In Render)

In class components it would be — render method is a function.

In function, we can call return inside if statement and it will not execute further on. It will have the same result as with Element variable above. We don’t need else here because when condition is satisfied execution will go on, otherwise it will be stopped on first render.

import React from 'react'
import { View, Text } from 'react-native'

const Card = ({ loading, error, title }) => {
  let content

  if (error) {
    content = <Text style={{ fontSize: 24, color: 'red' }}>Error</Text>
  } else if (loading) {
    content = <Text style={{ fontSize: 24, color: 'gray' }}>Loading...</Text>
  } else {
    content = (
      <View>
        <Text style={{ fontSize: 60 }}>{title}</Text>
      </View>
    )
  }

  return <View style={{ padding: 24 }}>{content}</View>
}

export default function App() {
  return (
    <View>
      <Card error={true} />
      <Card loading={true} />
      <Card loading={false} title="Title" />
    </View>
  )
}


3.3 Conditional (Ternary) Operator

Another common case: rendering a different React element for when a prop exists and when it doesn’t. We can accomplish this with the ternary operator. Note that a buttonTitle equal to the empty string, "", won’t render, since the empty string is a falsy value. If we did want it to, we could use buttonTitle === undefined to check for that case.

import React from 'react'
import { View, Text, Button } from 'react-native'

const Card = ({ title, buttonTitle }) => (
  <View>
    <Text style={{ fontSize: 60 }}>{title}</Text>
    {buttonTitle ? <Button title={buttonTitle} /> : null}
  </View>
)

export default function App() {
  return (
    <View>
      <Card title="Title" />
      <Card title="Title with button" buttonTitle="Press me!" />
    </View>
  )
}


Explaining The Array Example Solutions

In Previous example, we show that

dataEntries.length && (
  <View>
    <Text>Visible only when array is not empty</Text>
  </View>
)}

Now we understand that what really happens in above code is returning length to directly into JSX. It happens when length is falsy and it comes from logical operator implementation.

To simplify the example and make things more visible let’s assume that dataEntries.length is 0 and following View with Text component is <Component />. Now we have:

{0 && <Component />}

This expression returns 0 which is converted to string '0' and we can see it as an error in React Native or as an extra character on the web.

The quickest fix possible is to make sure that we don’t depend on falsy value but on boolean false.

Here are multiple fix scenarios:


Double Negation

{!!dataEntries.length && <Component />}


Classic Conversion

{Boolean(dataEntries.length) && <Component />}


Inline Condition

{(dataEntries.length > 0) && <Component />}


Ternary Operator

{dataEntries.length ? <Component /> : null}


Refactor, Rethink, Make It Safe

let coditionalComponent = null

if(dataEntries.length > 0){
	coditionalComponent = <Component />
}

That’s all about in this article.


Conclusion

In this article, We understood how to make conditional rendering safer in react native. We also explained what is happening and how to prevent further mistakes when we use Conditional Rendering .

Thanks for reading ! I hope you enjoyed and learned about Conditional Rendering concepts in React Native. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

You can find Other articles of CoolmonkTechie as below link :

You can also follow official website and tutorials of React Native as below links :

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

Summary
Article Name
React Native - How To Make Conditional Rendering Safer In React Native ?
Description
This article shows to make conditional rendering safer in react native. This explains to prevent mistakes during Conditional Rendering usage.
Author

Leave a Reply

Your email address will not be published. Required fields are marked *

Exit mobile version