I've upgraded from RN 0.54 to 0.57 and my app has pretty much fallen over due to using React Native Elements.

I took use of their error functionality on TextInput components which basically enabled props that you could style the error message and set your error message. Very convenient, however the upgrade has broke these and I'm now greeted with this error:

So I've delete that code and the error disappears, however I'm still receiving the issue when I run this code:

{ this.state.event.cards[i].fields[j].error && 

  <Text style={{ color: '#e74c3c', fontSize: 14, paddingLeft: 5 }}>
    {this.state.event.cards[i].fields[j].error}
  </Text>
}

When I begin to type in to a text input, it sets my error message to an empty string, so if an error is returned typing in the field will make the error go away.

As soon as this.state.event.cards[i].fields[j].error becomes a string, I get returned this error. However you can see I check to see if error exists, then I just display the error, or try to at least.

Another set of eyes would be grateful on this one.

Solution 1

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.

Solution 2

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

Solution 3

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.

Solution 4

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(even empty string), it must be wrapped with <Text /> in React Native, which is different from web.

Solution 5

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 ;)

Solution 6

For me, it happened because of an unopened curly brace inside JSX.

<View>
        {events.map(event => {
          return (
            <Card title={event.summary}>
              <Text>Date: {event.start.dateTime}</Text>
            </Card>
          );
        })}
        } <------------ that was the culprit
</View>

Solution 7

Had the same problem and @serdasenay comment made me realize the root cause.

Using the syntax {condition && <Element/>} is not wrong per se, but it's important to know whats going on.

The root of the problem is logic short-circuiting. In Javascript logic expressions evaluates, and && evaluates to the last true equivalent value. But not to true, but to the actual value before it's cast to boolean. That's what acctually allow this syntax to begin with. Since <Element/> is always true if condition is true, the expression evaluates to <Element/>

The problem arises when the condition is false. When a && expression fails, it evaluates to the first value i.e condition. But before it being cast to boolean. So, if you use a direct string or number as condition and it evaluates to false the logic expression will evaluate to that string or number. Ex.: {array.length && <List/>} with a empty array evaluates to {0} which throws the error.

The solution is to make sure condition is a real boolean value (and that works because React can deal with rendering booleans - it think React just ignores them). So do the following: {array.length > 0 && <List/>}

Solution 8

Delete space between components outside

<Text></Text>

Ex. Don't use

<Button> <Text>hi</Text></Button> 

But use

<Button><Text>hi</Text></Button>

Solution 9

In my case, this error occurred due to the presence of semi-colon ';' at the end of the closing of Text tag. For all those who don't get the appropriate answer above, try this. By removing semi-colon, the error disappeared.

Image of the Error code

As mentioned in the above image I also encountered this error due to the semi-colon ';'

Solution 10

From reading other answers here, this error message is vague and is shown for various reasons. I've gotten it when writing comments or even small white-space within views (crazy yeah...)

for example: <View> {props.children} </View>

must be changed to: <View>{props.children}</View>

Solution 11

For me it was the wrong import with IntelliSense. It imported the Button from'react-native-web' instead of 'react-native'. Once you run on the phone you get the this error.

Solution 12

This usually happens when you do inline conditional rendering. You should delete white space between Text and your condition like below.

{ this.state.event.cards[i].fields[j].error && <Text style={{ color: '#e74c3c', fontSize: 14, paddingLeft: 5 }}>
    {this.state.event.cards[i].fields[j].error}
  </Text>
}

Solution 13

In my case, I had to remove space between View tag and Text tag from

<View>  <Text style={{ color: "white"}}>Start</Text> </View>

to

<View><Text style={{ color: "white"}}>Start</Text></View>

Solution 14

As for me I had this error because of a trailing ';' I changed :

<Divider orientation="horizontal" />;

To :

<Divider orientation="horizontal" />

Solution 15

In my case, it was a semicolon at the end of JSX syntax.

// wrong:
<View>
  <MyComponent>;
</View>

// correct:
<View>
  <MyComponent>
</View>

Solution 16

I encountered the same error message in VSCode yet I didn't have /* Comments */ or any expressions. The solution was to remove the formatting in something like textedit or word and copy+paste the code back to vscode.

I do not know why or how it works (perhaps it specifically happens in VSCode), but the formatting issue is something I also have experienced with SDL in graphql...

Solution 17

Sometimes Prettier or your code formatter will add this to your JSX when you save.

<View>
{' '}
</View>

Remove this and you should be fine.

Solution 18

Use this code given below if the initial value is an empty string. Or conditionaly check with the initial value. Here I conditionaly check when the error is not empty then show the error.

{this.state.error !== '' && (
    <Text>
      {this.state.error}
    </Text>
)}

Solution 19

For me it was due to the misplacement of closing > in TouchableOpacity React native touchable Opacity.

Faulty code :

<TouchableOpacity>
        onPress={() => this.setState({ showOverLay: true })}
          <Image
            source={cardImage}
            resizeMode="contain"
            style={[
              styles.cardImage, cardImageStyle
            ]}
          />
</TouchableOpacity>

Good code :

  <TouchableOpacity
        onPress={() => this.setState({ showOverLay: true })}>
          <Image
            source={cardImage}
            resizeMode="contain"
            style={[
              styles.cardImage, cardImageStyle
            ]}
          />
</TouchableOpacity>

Solution 20

For me, the error was because I initialized the state object as an empty string.

const [category, setCategory] = useState("")

If the state is going to be an object, then it must be set to null in the beginning.

const [category, setCategory] = useState(null)

The solved the problem.

Solution 21

Conditions with '' (empty string) not working. Change them to null

Not Working:

<ButtonBorderLarge
    buttonText={'Choose certificate'}
    onPressHandler={pickCertificate}
    icon={docName ? 'check' : ''}
/>

Working:

<ButtonBorderLarge
    buttonText={'Choose certificate'}
    onPressHandler={pickCertificate}
    icon={docName ? 'check' : null}
/>

Solution 22

Solution

!! will resolve this issue.

{!!error && <Text>{error}</Text>}

Explanation

  • if we use single not ! operate and assign empty "" string then !"" will become true and will render empty string because we are converting string to boolean !"" => true

Solution 23

If there is any space between your and (in same line) then also this error can come.

**eg: <Text> <Button>click me<Button><Text>**

           ^(make sure that you have no space if it is in same line)



  

make sure to avoid space between two tags if it is in same line.

By doing this I solved this issue.

Solution 24

 <React.Fragment>
      {this.props.title ? (
        <React.Fragment> 
          <Text>  true </Text>
        </React.Fragment>
        ):(             
           <React.Fragment> 
          <Text>  false </Text>
          <Text>  false </Text>
        </React.Fragment>

You have to wrap with View tag or React.Fragment tag and inside you need also wrap if element more then one

Solution 25

try this :

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

Solution 26

{this.state.password.length > 0 && <Text>}

This will throw the same error, because it returns undefined. We can render it like this -

{this.state.password.length > ? <Text> : null}

Solution 27

In my case some part of the code was out side the text component for example:
<RadioForm style={styles.radiobutton} 
                      radio_props={hobbies}
                      initial={1}
                      onPress={(value) => {ToastAndroid.show(value.toString(), ToastAndroid.SHORT)}}
                      buttonSize={4.5}
                      buttonOuterSize={19}
                      selectedButtonColor={'green'}
                      selectedLabelColor={'green'}
                      labelStyle={{ fontSize: 14, }}
                      disabled={false}
                      formHorizontal={true}
             />
<RadioForm

this above line < RadioForm is left unclosed that is the reason

Solution 28

I had the same issue and the mistake was adding space between the children and the component such as {children}

Note: Remove any space close to {children}

 <Provider value={something}>{children}</BlogContext.Provider>

Solution 29

This occurred for me because I was using a lower-case function name by accident:

export const p = (props) => {
  return (
    <Text style={[styles.p]}>{props.children}</Text>
  );
};

Should be:

export const P = (props) => {
  return (
    <Text style={[styles.p]}>{props.children}</Text>
  );
};

Notice in the second one the p is capitalized. This is needed in order for the components to be detected as React Native components.

Solution 30

I had the same problem, In my case I had an <AppText> component which shows simple formatted <Text> under the hood.

First code was like

<AppText> </AppText>

while I was trying different things I just wrote it with self-closing syntax

<AppText />

then problem was suddenly solved.

I think it was just about a special & invisible character I wrote between tags by mistake or this character was coming from VSCode by auto-complete feature or snippets, because I couldn't repeat the error by placing a space.