Invariant Violation: Text strings must be rendered within a <Text> component
JavascriptReact NativeJavascript Problem Overview
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.
Javascript Solutions
Solution 1 - Javascript
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 - Javascript
Also occurs when you have /* Comments */ in your return() function.
Solution 3 - Javascript
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 - Javascript
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 should be wrapped with <Text />
in React Native, which is different from web.
Solution 5 - Javascript
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 - Javascript
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 - Javascript
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 - Javascript
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 - Javascript
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.
As mentioned in the above image I also encountered this error due to the semi-colon ';'
Solution 10 - Javascript
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 11 - Javascript
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 12 - Javascript
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 13 - Javascript
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 14 - Javascript
As for me I had this error because of a trailing ';' I changed :
<Divider orientation="horizontal" />;
To :
<Divider orientation="horizontal" />
Solution 15 - Javascript
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 16 - Javascript
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 17 - Javascript
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 18 - Javascript
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 19 - Javascript
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 20 - Javascript
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 21 - Javascript
Solution
!!
will resolve this issue.
{!!error && <Text>{error}</Text>}
Explanation
- if we use single not
!
operate and assign empty""
string then !"" will becometrue
and will render empty string because we are converting string to boolean!"" => true
Solution 22 - Javascript
<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 23 - Javascript
try this :
<>
<View>
{this.state.error &&
<Text>
Error message: {this.state.error}
</Text>
</View>
</>
Solution 24 - Javascript
{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 25 - Javascript
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 26 - Javascript
I had the same issue and the mistake was adding space between the children and the component such as
Note: Remove any space close to {children}
<Provider value={something}>{children}</BlogContext.Provider>
Solution 27 - Javascript
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 28 - Javascript
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.
Solution 29 - Javascript
In my case it occurred because comments in render function
// Some comment here
Solutions:
- Remove the comment
- or make it like this
{/* Same comment here*/}
Solution 30 - Javascript
This error occurs when you have /*Commented code*/
in your return()
function.
Spent a good chunk of the day doing completely unrelated tasks to try and fix this one.
Solution 31 - Javascript
There is an operator !! which converts a string type to boolean and makes it false when variable is an empty string:
{!!error &&
<Text>
Error message: {error}
</Text>}
Solution 32 - Javascript
This below code also check empty string and truthy value.
return(
<View>
{!!this.state.error && <Text>{this.state.errorMessage}</Text>}
</View>
);
Solution 33 - Javascript
remove mark ()
from outside any components, this is use in after return and if statement in JSX ()
This is wrong:
<View>(<Button/>)</View>
This is true:
<View><Button/></View>
Solution 34 - Javascript
In my case, I was naming the state text like the name of the component to make sure it s a different name.
Solution 35 - Javascript
In my case Tanveer Rifu's answer worked. But in addition to that if you have spaces in your return statement, you can fix this by wrapping it in parenthesis ()
and using one line per each tag.
Example, instead of
const HelloWorld = () => {
let counter = 0;
return <View> <Button title="Increment"> </Button><Text>{ counter}</Text> </View>
}
You can wrap it as below
const HelloWorld = () => {
let counter = 0;
return (
<View>
<Button title="Increment"></Button>
<Text>{counter} </Text>
</View>
)
}
But still if you're going to have more than one elemenent in single line do not leave spaces between the different tags.
Solution 36 - Javascript
It is giving error on <Pressable>
too. So avoid pressable instead of react native buttons. It may helpful to the people who are using react-native 6 or above.
Or else try this way
<Pressable titleSize={20} style={styles.button}>
<Text>Pressable tab
Solution 37 - Javascript
In my case I was importing
import { Button, View } from 'react-native-web';
instead of
import { Button, View } from 'react-native';
Make sure you are importing from correct package.
Solution 38 - Javascript
If there is any space between your
Solution 39 - Javascript
i'm an absolute beginner to react native and my mistake was importing Text, Flatlist from react-native-web instead of just 'react-native', it's automatically happens on vs code and i don't know why!
DON'T
import { Text, FlatList, StyleSheet } from "react-native-web";
DO
import { Text, FlatList, StyleSheet } from "react-native";
Solution 40 - Javascript
this.state.recording ?(<Text>{this.secondsToMMSS(this.state.seconds)}</Text>) : (null)
text string must be rendered with in
Solution 41 - Javascript
ok, so if you came this far down, its because you probably have the same issues as me for example:
return <View key={r}> {columns} </View>
and:
return <View style={styles.container}> {rows} </View>
you see there is a space beetween "> {" yeah, that's the whole issue, try deleting those.
Solution 42 - Javascript
Just remove the comments from the code, then it will work fine. I don't know any other alternative by the way! :)