I am trying to make a chat app in react native, with firebase for data and authentication.
I am now trying to make the screen which will display a chat feed, fetching a collection of messages from my firebase project using firestore.
During my try to make such a screen, a error occured;
"Text strings must be rendered with <Text> component", along with indicator showing this was the error, on setLoading(false)
useEffect(() => {
const unsubscribe = firestore()
.collection('chats')
.orderBy('createdAt', 'asc')
.limitToLast(15)
.onSnapshot(querySnapshot => {
const chatsArr = [];
querySnapshot.forEach(doc => {
const id = doc.id;
const data = doc.data();
chatsArr.push({id, ...data});
});
setLoading(false);
setChats(chatsArr);
});
return () => {
unsubscribe();
setLoading(false);
};
}, []);
Here is the stack:
Error: Text strings must be rendered within a <Text> component.
This error is located at:
in RCTView (created by View)
in View (created by MainScreen)
in MainScreen (created by SceneView)
in StaticContainer
in EnsureSingleNavigator (created by SceneView)
in SceneView (created by SceneView)
in RCTView (created by View)
in View (created by DebugContainer)
in DebugContainer (created by MaybeNestedStack)
in MaybeNestedStack (created by SceneView)
in RCTView (created by View)
in View (created by SceneView)
in RNSScreen
in Unknown (created by InnerScreen)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by InnerScreen)
in InnerScreen (created by Screen)
in Screen (created by SceneView)
in SceneView (created by NativeStackViewInner)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by ScreenStack)
in RNSScreenStack (created by ScreenStack)
in ScreenStack (created by NativeStackViewInner)
in NativeStackViewInner (created by NativeStackView)
in RNCSafeAreaProvider (created by SafeAreaProvider)
in SafeAreaProvider (created by SafeAreaInsetsContext)
in SafeAreaProviderCompat (created by NativeStackView)
in NativeStackView (created by NativeStackNavigator)
in PreventRemoveProvider (created by NavigationContent)
in NavigationContent
in Unknown (created by NativeStackNavigator)
in NativeStackNavigator (created by App)
in EnsureSingleNavigator
in BaseNavigationContainer
in ThemeProvider
in NavigationContainerInner (created by App)
in App
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in Chattr(RootComponent), js engine: hermes
And here is all the code of the MainScreen:
import React, {useEffect, useState} from 'react';
import auth from '@react-native-firebase/auth';
import firestore from '@react-native-firebase/firestore';
import {
View,
StyleSheet,
Text,
Alert,
ActivityIndicator,
FlatList,
} from 'react-native';
import ChatMessage from '../components/ChatMessage';
import SignOutButton from '../components/SignOutButton';
const MainScreen = () => { // Input text
const [chats, setChats] = useState([]); // Chat messages
const [loading, setLoading] = useState(true);
const handleSignOut = async () => await auth().signOut();// Loading state
useEffect(() => {
const unsubscribe = firestore()
.collection('chats')
.orderBy('createdAt', 'asc')
.limitToLast(15)
.onSnapshot(querySnapshot => {
const chatsArr = [];
querySnapshot.forEach(doc => {
const id = doc.id;
const data = doc.data();
chatsArr.push({id, ...data});
});
setLoading(false);
setChats(chatsArr);
});
return () => {
unsubscribe();
setLoading(false);
};
}, []);
if (loading) {
return <ActivityIndicator />; // Show loader while loading chats
} else {
const username = auth().currentUser.displayName;
return (
<View style={styles.container}>
// Top app bar
<View style={styles.textContainer}>
<Text style={styles.text}>{username}</Text>
<SignOutButton handleClick={handleSignOut} />
</View>
// Chats container
<View style={styles.chatStyle}>
{chats && (
<FlatList
data={chats}
renderItem={({item}) => <ChatMessage key={item.id} chat={item} />}
/>
)}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
chatStyle: {
alignItems: 'center',
justifyContent: 'center',
height: '90%',
margin: 0,
padding: 0,
marginLeft: 'auto',
marginRight: 'auto',
// overflowY: 'scroll',
},
container: {
height: '100%',
width: '100%',
margin: 0,
marginTop: 0,
marginBottom: 0,
padding: 0,
paddingBottom: '15%',
paddingTop: 0,
backgroundColor: '#151718',
alignItems: 'flex-start',
justifyContent: 'space-between',
},
inputContainer: {
width: '100%',
height: 60,
position: 'absolute',
flexDirection: 'row',
bottom: 0,
left: 0,
right: 0,
margin: 0,
padding: 0,
paddingBottom: 0,
backgroundColor: '#151718',
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderColor: '#1e2123',
borderLeftWidth: 0,
borderRightWidth: 0,
borderBottomWidth: 0,
},
text: {
fontWeight: '600',
fontSize: 20,
color: '#030303',
marginRight: 'auto',
marginLeft: 8,
padding: 4,
},
textContainer: {
flexDirection: 'row',
height: 60,
width: '100%',
margin: 0,
padding: 8,
elevation: 6,
backgroundColor: '#ffa600',
alignItems: 'center',
justifyContent: 'space-between',
},
});
export default MainScreen;
My question is, why am i getting this error? I have really no clue at the moment where this is occuring and i have sat for some hours now struggling to find a solution.
Ran npm start, npm start android, app builded succesfully and error occured, with no screen rendered behind the error message.
2
Answers
Remove the following from your code
This is not viewed as a comment but as text in the return statement so either remove it or change it to the following
The error message you’re seeing, "Text strings must be rendered within a component," typically means that you are attempting to render a plain string outside of a component at some point in your component. React Native need this in order to render text.
The following line of code in your MainScreen component may be the source of the problem:
Make sure the string username is valid. To avoid the problem, you may need to handle the condition where the username is null or undefined. The component can be conditionally rendered or you can use a default value.
This guarantees that the default username will be ‘Guest’ in the event that it is false (null or undefined). Adapt this to the logic of your application.
If the problem still occurs, you might also want to make sure that you are not attempting to render a bare string without first enclosing it in a component by looking at the ChatMessage component.
Furthermore, confirm that no additional code segments render plain strings in the absence of a component. The setLoading(false) line is the source of the error message; however, other components’ rendering may be the cause of the problem.