Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I've shot myself in the foot too many times over this, so I'm leaving this here for the next person not to...

Whenever you see

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

99% of cases will be caused by using conditional rendering with only && instead of ternary ? : statements. Why? Because when your condition resolves to undefined, there are no components there, as opposed to null or an empty array which would have safely showed an empty space and save your life from the red screen of hell.

Change ALL OF YOUR LOGICAL CONDITIONAL RENDERS into ternary renditions.

ie:

DON'T DO

widgetNumber === 10 && <MyComponent />

DO DO

widgetNumber === 10 ? <MyComponent /> : null

Every Single Time. Please. For the love of react native.


For me the following code works fine, as long as this.state.error === undefined or it is not an empty string.

render() {
  return (
    <View>
      {this.state.error &&

        <Text>
          Error message: {this.state.error}
        </Text>
      }
    </View>
  );
}

If the error state is changed to empty string '', you will have the aforementioned exception: Invariant Violation: Text strings must be rendered within a <Text> component

The reason of that is, when this.state.error === '', the following expression will be evaluated as empty string, i.e., '', and this will cause Invariant Violation: Text strings must be rendered within a <Text> component

{this.state.error &&

  <Text>
    Error message: {this.state.error}
  </Text>
}

When this.state.error === undefined, the expression will be evaluated as undefined, which is what we expect, and it's fine.


Also occurs when you have /* Comments */ in your return() function.


I'd use !! which I call bang bang operator to boolianize error. That should work.


{!!this.state.error && (
  <Text>
    Error message: {this.state.error}
  </Text>
)}

If error is a string, whatever your text should be wrapped with <Text /> as the error message says in React Native, which is different from web.


This occurs when you use a string or numeric values in && operators.

For example:

const [a, setA] = useState('')
const [b, setB] = useState(0)

Here, both a && <View /> and b && <View /> will throw this error.

You need to have this conditional value as an true/false, null, or undefined data type.

Instead of using the string and numeric data types straight forward, you should convert them to Boolean type.

Correct implementation should be:

!!a && <View /> and !!b && <View />

or

for negation; !a && <View /> and !b && <View />

Happy learning ;)