React Navigation Is there a way to refer to a navigator from the parent component? - javascript

I understand that navigation and route props are automatically passed to the target screen when you navigate. So you can access navigation when you're in that screen, say screen B.
What I want to do is in Screen A, where the navigator is defined, I'd like to be able to setParams every so often. How can I refer to the navigator in this case?
For example, I would like to do this:
navigator.screen('posts').setParams({videoData: stuff});
A.js
const A = () => {
const Tab = createMaterialTopTabNavigator();
const navigator = <Tab.Navigator>
<Tab.Screen name="posts" component={FeedList} />
</Tab.Navigator>;
useEffect(()=> {
fetchStuff((stuff)=> {
navigator.screen('posts').setParams({videoData: dataState});
});
},[]);
return <>{navigator}</>;
}
Inside the useEffect, I ideally would be able to dynamically set the route params of the target screen.
I tried using initialParams and a state, but the initialParams doesn't seem to update in the target screen when the state changes. (So, I would accept that as an answer too, if you know why that's not working.)
not working initialParams example:
const A = () => {
const [dataState, setDataState] = useState(null);
const Tab = createMaterialTopTabNavigator();
useEffect(()=> {
fetchStuff((stuff)=> {
setDataState(stuff); // this doesn't seem to update initialParams
});
},[]);
return <Tab.Navigator>
<Tab.Screen name="posts" component={FeedList} initialParams={{videoData: dataState}} />
</Tab.Navigator>;
}

You can use setParams function.
Here is the code of updating of the state of a nested tab's screen after 3 seconds.
import React, {useContext, useState, createContext, useEffect} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import {createStackNavigator} from '#react-navigation/stack';
import {CommonActions} from '#react-navigation/native';
const Stack = createStackNavigator();
const KeyContext = createContext();
const DELAY_TIME = 3000;
const KeyContextProvider = (props) => {
const [routeKey, setRouteKey] = useState(null);
return (
<KeyContext.Provider
value={{key: routeKey, setKey: (value) => setRouteKey(value)}}>
{props.children}
</KeyContext.Provider>
);
};
const AScreen = ({navigation}) => {
const Tab = createBottomTabNavigator();
const {key} = useContext(KeyContext);
React.useEffect(() => {
if (key) {
setTimeout(() => {
navigation.dispatch({
...CommonActions.setParams({value: 'Updated state'}),
source: key,
});
}, DELAY_TIME);
}
}, [navigation, key]);
return (
<Tab.Navigator>
<Tab.Screen
name="screen B"
component={BScreen}
initialParams={{value: 'Initial state'}}
/>
<Tab.Screen name="screen C" component={CScreen} />
</Tab.Navigator>
);
};
const BScreen = ({route}) => {
const val = route.params?.value || null;
const {setKey} = useContext(KeyContext);
useEffect(() => {
setKey(route.key);
}, [route, setKey]);
return (
<View style={styles.screen}>
<Text>Screen B</Text>
<Text>{val}</Text>
</View>
);
};
const CScreen = () => {
return (
<View style={styles.screen}>
<Text>Screen C</Text>
</View>
);
};
export default function App() {
return (
<KeyContextProvider>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Screen A" component={AScreen} />
</Stack.Navigator>
</NavigationContainer>
</KeyContextProvider>
);
}
const styles = StyleSheet.create({
screen: {flex: 1, justifyContent: 'center', alignItems: 'center'},
});

Related

How to solve undefined is not a function

I'm making a ChatApp on ReactNative, on this part I'm trying to implement a SignOut function, but i don't understand what is wrong here.
enter image description here
The error is "undefined is not a function (near '...navigation.setOptions...')
The error is on the function:
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<TouchableOpacity style={{ marginRight: 10 }} onPress={onSignOut}>
//<AntDesign name="logout" size={24} color={"#808080"} style={{marginRight:10}}/>
</TouchableOpacity>
)
});
}, [navigation]);
import React, {
useState,
useEffect,
useLayoutEffect,
useCallback,
} from "react";
import { TouchableOpacity, Text } from "react-native";
import { GiftedChat } from "react-native-gifted-chat";
import {
collection,
addDoc,
query,
onSnapshot
} from 'firebase/firestore';
import { signOut } from 'firebase/auth';
import { database } from "../config/firebase";
import { useNavigation } from "#react-navigation/native";
import {AntDesign} from "#expo/vector-icons";
import { Colors } from "react-native/Libraries/NewAppScreen";
import { auth } from "../config/firebase"
export default function Chat() {
const [messages, setMessages] = useState([]);
const navigation = useNavigation();
const onSignOut = () => {
signOut(auth).catch(error => console.log(error));
};
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<TouchableOpacity style={{ marginRight: 10 }} onPress={onSignOut}>
//<AntDesign name="logout" size={24} color={"#808080"} style={{marginRight:10}}/>
</TouchableOpacity>
)
});
}, [navigation]);
useLayoutEffect(() => {
const collectionRef = collection(database, 'chats');
const q = query(collectionRef, orderBy('createAt', 'desc'));
const unsubscribe = onSnapshot(q, snapshot => {
console.log('snapshot');
setMessages(
snapshot.docs.map(doc => ({
_id: doc.id,
createdAt: doc.data().createdAt,
text: doc.data().text,
user: doc.data().user,
}))
)
});
return () => unsubscribe();
}, []);
const onSend = useCallback((messages = []) => {
setMessages(previousMessages => GiftedChat.append(previousMessages, messages));
const { _id, createdAt, text, user } = messages[0];
addDoc(collection(database, 'chats'), {
_id,
createdAt,
text,
user,
});
}, []);
return (
<GiftedChat
messages={messages}
onSend={messages => onSend(messages)}
user = {{
_id: auth?.currentUser?.email,
avatar: 'https://i.pravatar.cc/300'
}}
/>
);
}
The Navigation is on this part
This is the main part of the code, here i make the navigation into de login and signup part and the chat and home screens.
'''App.js Javascript
import React, {useState, createContext, useContext, useEffect} from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import { View, ActivityIndicator } from "react-native";
import { onAuthStateChanged } from "firebase/auth";
import Chat from "./src/screens/Chat";
import Login from "./src/screens/Login";
import Signup from "./src/screens/Signup";
import Home from "./src/screens/Home"
import { auth } from "./src/config/firebase";
const Stack = createStackNavigator();
const AuthenticatedUserContext = createContext({});
const AuthenticatedUserProvider = ({ children }) => {
const [user, setUser] = useState(null);
return (
<AuthenticatedUserContext.Provider value = {{user, setUser}}>
{children}
</AuthenticatedUserContext.Provider>
)
}
function AuthStack () {
return (
<Stack.Navigator defaultScreenOptions={Login} screenOptions={{headerShown: false}}>
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Signup" component={Signup} />
</Stack.Navigator>
)
}
function ChatStack () {
<Stack.Navigator defaultScreenOptions={Home}>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Chat" component={Chat} />
</Stack.Navigator>
}
function RootNavigator () {
const {user, setUser} = useContext(AuthenticatedUserContext);
const [loading, setLoading] = useState(true);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth,
async authenticatedUser => {
authenticatedUser ? setUser(authenticatedUser) : setUser(null);
setLoading(false);
}
);
return () => unsubscribe();
}, [user]);
if(loading) {
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<ActivityIndicator size="large" />
</View>
)
}
return (
<NavigationContainer>
{ user ? <ChatStack /> : <AuthStack />}
</NavigationContainer>
)
}
export default function App(){
return (
<AuthenticatedUserProvider>
<RootNavigator />
</AuthenticatedUserProvider>
)
}
'''

ReactNative Context returns undefined when trying to access a value

I am trying to use the values/functions from my context but every time I console.log a value that Coes from context the value is undefined.
This is my Context:
import { NativeStackNavigationProp } from '#react-navigation/native-stack';
import React, {createContext, FC, useEffect } from 'react';
import { useState } from 'react';
import {fbInit, setNewUserFireStore, subscribeUserFS } from '../services/FirebaseServices';
const initialState = {
signedIn: false,
}
export const FirebaseContext = createContext();
export const FirebaseContextProvider = ({children}) => {
const [isUserSignedIn, setIsUserSignedIn] = useState(initialState.signedIn);
useEffect(() => {
fbInit();
})
const testLog = () => {
console.log("TAG Test Log Func")
}
return (
<FirebaseContext.Provider value={{isUserSignedIn, setIsUserSignedIn}}>
{children}
</FirebaseContext.Provider>
);
}
This is where I am trying to use the values (I am trying to log the values when I press the Button)
import { useNavigation } from '#react-navigation/native';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import {Button, Card, TextInput} from 'react-native-paper';
import { FirebaseContext } from '../../context/FirebaseContext';
import React, {useContext, useEffect, useState } from 'react';
const initialUserState = {
userName: 'Nicole Lopez',
password: '1001008888',
}
export default function LoginScreen() {
const [disabled, setDisabled] = useState(false);
const [userState, setUserState] = useState(initialUserState);
const { fbContext } = useContext(FirebaseContext);
const navigation = useNavigation();
const onInputChange = (field, value) => {
setUserState({
...userState,
[field]: value
})
}
useEffect(() => {
setDisabled(userState.userName.length === 0 || userState.password.length === 0);
}, [userState.userName, userState.password])
return (
<View style={styles.container}>
<Card style={styles.card}>
<TextInput
mode="outlined"
label="Förnamn & Efternman"
defaultValue={userState.userName}
onChangeText={text => onInputChange("username", text)}
right={<TextInput.Icon name="account" onPress={() => {
}}/>}
style={styles.textInput}/>
<TextInput
mode="outlined"
label="Anställningsnummer 100100xxxx"
defaultValue={userState.password}
right={<TextInput.Icon name="lock"/>}
onChangeText={text => onInputChange("password", text)}
style={styles.textInput}/>
</Card>
<View style={styles.buttonRow}>
<Button
color={disabled ? "gray" : undefined}
disabled={disabled}
mode={'contained'}
icon={'login'}
onPress={() => {
console.log("TAG isUserSignedIn: " + fbContext?.isuserSignedIn)
//fbContext?.testLog()
//console.log("TAG LOGIN BTN PRESSED")
//navigation.navigate('HomeScreen')
}}>Login</Button>
</View>
</View>
);
}
This is my App.js:
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import {StackScreens} from './src/helpers/types';
import { NavigationContainer, useNavigationContainerRef } from '#react-navigation/native';
import LoginScreen from './src/screens/LoginScreen/LoginScreen';
import HomeScreen from './src/screens/HomeScreen/HomeScreen';
import {doc, getFirestore, onSnapshot, setDoc, Unsubscribe as UnsubscribeFS} from 'firebase/firestore';
import { FirebaseContextProvider, FirebaseContext } from './src/context/FirebaseContext';
import { useContext } from 'react';
//import { navigationRef } from './RootNavigation';
//const userDocument = firestore().collection("users").doc('Cstl3bA9xwwH3UwHZJhA').get();
const Stack = createNativeStackNavigator();
export default function App() {
return (
<FirebaseContextProvider>
<Content />
</FirebaseContextProvider>
);
}
export const Content = () => {
const navigationRef = useNavigationContainerRef();
const firebaseContext = useContext({FirebaseContext});
return (
<NavigationContainer ref={navigationRef}>
<Stack.Navigator initialRouteName="LoginScreen">
<Stack.Screen name="LoginScreen" component={LoginScreen} />
<Stack.Screen name="HomeScreen" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Don't know what I have missed, I have installed the packages, I have tried to log different values but all seem to be undefined :/
I believe it is undefined because you're trying to destructure the context value, maybe
const { fbContext } = useContext(FirebaseContext);
should be
const fbContext = useContext(FirebaseContext);
For someone getting undefined from context, check on which level you placed your context provider. If you want to use context in a component you should wrap this component in a context provider outside of this component!
Incorrect way
const Component = () => {
const { value1, value2 } = useContext(MyContext); //here context value will be undefined
return (
<ContextProvider>
//Component content
</ContextProvider>
)
}
Correct way
const ComponentA = () => {
const { value1, value2 } = useContext(MyContext);
return(//Component A content)
}
const ComponentB = () => {
return(
<ContextProvider>
<ComponentA/>
</ContextProvider>
)
}

react native how to show up badge when my app run

I've been facing a problem for 1 week. My question is I would like to show up new message badge without clicking message room when I run my app I can show the badge after clicking message room.
when I run my app. Home page.
and then I clicked Message room Now I can see the badge
ChatList component src/Components/ChatList
const [badgeCount, setBadgeCount] = useState(0);
const {badgeStateDispatch} = useContext(GlobalContext);
const unReadMessageQuery = db
.collection('chats')
.doc(id)
.collection('messages')
.where('user', '==', recipientEmail)
.where('unread', '==', true);
const [unReadMessageToBadge] = useCollection(unReadMessageQuery);
useEffect(() => {
const badgeMessagesCount = unReadMessageToBadge?.size;
console.log(badgeMessagesCount);
setBadgeCount(badgeMessagesCount);
badgeStateDispatch({type: BADGE_SHOW});
}, [unReadMessageToBadge]);
reducer
import {BADGE_SHOW, BADGE_RESET} from '../../Constants/actionTypes';
const badgeCount = (state, {type, payload}) => {
switch (type) {
case BADGE_SHOW:
return {...state, badge: (state.badge = true)};
case BADGE_RESET:
return {...state, badge: (state.badge = null)};
default:
return state;
}
};
export default badgeCount;
TabNavi src/Navigator/Tabnavi.js
import React, {useContext} from 'react';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import HomeStackNavi from './HomeStackNavi';
import ProfileStackNavi from './ProfileStackNavi';
import MessageStackNavi from './MessageStackNavi';
import Entypo from 'react-native-vector-icons/Entypo';
import Icon from 'react-native-vector-icons/FontAwesome';
import colors from '../Assets/theme/colors';
import {GlobalContext} from '../Context/GlobalProvider';
const Tab = createBottomTabNavigator();
const TabNavi = () => {
const {
badgeState: {badge},
} = useContext(GlobalContext);
return (
<Tab.Navigator
tabBarOptions={{
activeTintColor: colors.white,
inactiveTintColor: colors.gray,
style: {backgroundColor: colors.primary},
}}>
<Tab.Screen
name="Home"
component={HomeStackNavi}
options={{
tabBarIcon: () => <Icon name="home" size={25} color={colors.white} />,
}}
/>
<Tab.Screen
name="Messages"
component={MessageStackNavi}
options={{
tabBarIcon: () => (
<Entypo name="message" size={25} color={colors.white} />
),
tabBarBadge: badge,
tabBarBadgeStyle: {
top: Platform.OS === 'ios' ? 0 : 9,
minWidth: 10,
maxHeight: 10,
borderRadius: 7,
fontSize: 10,
},
}}
/>
<Tab.Screen
name="Profile"
component={ProfileStackNavi}
options={{
tabBarIcon: () => <Icon name="user" size={25} color={colors.white} />,
}}
/>
</Tab.Navigator>
);
};
export default TabNavi;
Edit: This is the parent component of the ChatList.
const ChatRoomList = () => {
const [user] = useAuthState(auth);
if (!user || !user.email) return;
const {badgeStateDispatch} = useContext(GlobalContext);
const renderItem = useCallback(({item}) => <ChatList item={item} />, []);
const keyExtractor = useCallback(item => item.id, []);
const userChatRef = db
.collection('chats')
.where('users', 'array-contains', user.email);
const [chatsSnapshot] = useCollection(userChatRef);
const [chatList, setChatList] = useState([]);
useEffect(() => {
const chatData = new Array();
chatsSnapshot?.docs.map(chat => {
chatData.push({id: chat.id, users: chat.data().users});
});
setChatList(chatData);
}, [chatsSnapshot]);
useFocusEffect(
React.useCallback(() => {
badgeStateDispatch({type: BADGE_RESET});
}, []),
);
return (
<View>
<FlatList
data={chatList}
renderItem={renderItem}
keyExtractor={keyExtractor}
initialNumToRender={7}
showsVerticalScrollIndicator={false}
/>
</View>
);
};
export default ChatRoomList;
I'd really appreciate your help.
Your issue is that your call to check for unread messages is in your ChatList component which is in your second tab. react-navigation only renders that component when you navigate to the second tab so therefore this code is only running when you select that tab.
You must move this call elsewhere, either into a higher order component or out of the React tree altogether, although this would require a bit of reworking as you're relying on hooks.

How to use react hooks on react-native with react-navigation

This is App.js using react-navigation. There are two screens on it called HomeScreen and AddScreen.
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import HomeScreen from './src/HomeScreen';
import AddScreen from './src/AddScreen';
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Add" component={AddScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
And This is home Screen. There is a 'items' in 'useState. It is gived through Add by navigation as props.
import * as React from 'react';
import PropTypes from 'prop-types';
import { View, Text, Button } from 'react-native';
function HomeScreen({ navigation, route }) {
const [items, setItems] = React.useState([]);
React.useEffect(() => {
if (route.params?.items) {
// Post updated, do something with `route.params.post`
// For example, send the post to the server
console.log('saved');
}
}, [route.params?.items]);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="Create post"
onPress={() => navigation.navigate('Add', { items, setItems })}
/>
<View>
{items.map((item, i) => {
return (
<View>
<Text>{item.itemName}</Text>
<Text>{item.itemPrice}</Text>
</View>
);
})}
</View>
</View>
);
}
HomeScreen.propTypes = {
navigation: PropTypes.object.isRequired,
};
export default HomeScreen;
And AddScreen receives 'items' as route.params.
And it use 'setItems' to push his own data in it.
After adding, navigation return to HomeScreen with items that is added with new item.
import * as React from 'react';
import PropTypes from 'prop-types';
import { View, Text, Button, TextInput } from 'react-native';
function AddScreen({ route, navigation }) {
const { items, setItems } = route.params;
const [itemName, setItemName] = React.useState('');
const [itemPrice, setItemPrice] = React.useState('0');
const addItem = () => {
setItems([...items, { itemName, itemPrice }]);
setItemName('');
setItemPrice('0');
};
return (
<View>
<TextInput
multiline
placeholder="What's on your mind?"
value={itemName}
onChangeText={setItemName}
/>
<TextInput
multiline
placeholder="What's on your mind?"
value={itemPrice}
onChangeText={setItemPrice}
/>
<Button
title="Done"
onPress={() => {
addItem();
// Pass params back to home screen
navigation.navigate('Home', items);
}}
/>
</View>
);
}
AddScreen.propTypes = {
navigation: PropTypes.object.isRequired,
route: PropTypes.object.isRequired,
};
export default AddScreen;
It works well on my purpose.
But I'm not sure whether this way is correct or not using react hooks to give and receive data from parent to child.
Could you modify my code ?
You should consider using React Context API https://uk.reactjs.org/docs/context.html. Its dedicated to sharing the common state (items in your case). Here is an example:
You should create a common context for items:
ItemsState.js
import React, { useState, useContext } from 'react';
const ItemsContext = React.createContext([]);
export const ItemsProvider = ({ children }) => {
return (
<ItemsContext.Provider value={useState([])}>
{children}
</ItemsContext.Provider>
);
}
export const useItems = () => useContext(ItemsContext);
Then share the context between screens with provider in App.js like this
import {ItemsProvider} from 'ItemsState';
function App() {
return (
<ItemsProvider> // share the items between both screens
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Add" component={AddScreen} />
</Stack.Navigator>
</NavigationContainer>
</ItemsProvider>
);
}
Then use items context in each screen like this AddScreen.js
import {useItems} from './ItemsState';
function AddScreen({ route, navigation }) {
const [items, setItems] = useItems(); // <- using items context as global useState
const [itemName, setItemName] = React.useState('');
const [itemPrice, setItemPrice] = React.useState('0');
const addItem = () => {
setItems([...items, { itemName, itemPrice }]);
setItemName('');
setItemPrice('0');
};
return (
<View>
<TextInput
multiline
placeholder="What's on your mind?"
value={itemName}
onChangeText={setItemName}
/>
<TextInput
multiline
placeholder="What's on your mind?"
value={itemPrice}
onChangeText={setItemPrice}
/>
<Button
title="Done"
onPress={() => {
addItem();
// Pass params back to home screen
navigation.navigate('Home', items);
}}
/>
</View>
);
}
You can also use useReducer hook and make more Redux-like. Check out this article
https://medium.com/simply/state-management-with-react-hooks-and-context-api-at-10-lines-of-code-baf6be8302c
in order to share data between components you can use Context API or Redux, passing full objects through navigation routes is an anti-pattern, you can find more information in the docs
https://reactnavigation.org/docs/params/#what-should-be-in-params

Conditional rendering with React Hooks : loading

I am learning how to use React Hooks and have been stuck for many hours on something that's supposed to be very simple.
I am trying to display a a text if the state variable "loading" is true. If it's false, I want to display something else.
No matter what I try, "loading" is always false or at least, the UI does not appear to reflect its value.
here is the code:
import React, {useState, useEffect} from 'react';
import {View, SafeAreaView, Text} from 'react-native';
const testScreen= (props) => {
const [loading, setLoading ] = useState(true);
useEffect(() => {
setLoading(false);
}, []);
if(loading)
{
return <Text>Hi</Text>;
}
else
{
return<Text.Hey</Text>
}
}
export default testScreen;
Any help will be more than welcome and I am sorry if this is very basic.
UPDATE: Here is the actual code I am working with. SetLoading is supposed to update the state variable to false but never does or at least, the UI des not render.
import React, {useState, useEffect} from 'react';
import {View, SafeAreaView, Text, ActivityIndicator} from 'react-native';
import CategoryTag from '../Components/CategoryTag';
import firestore from '#react-native-firebase/firestore';
const CategoryScreen = (props) => {
const topicCollection = firestore().collection('Topics')
.where("active","==",true);
//hooks for topics
const [topics,setTopics] = useState([]);
const [loading, setLoading ] = useState(true);
//get all active topics
useEffect(() => {
return topicCollection.onSnapshot(querySnapshot => {
const list = [];
querySnapshot.forEach(doc => {
const { active, name } = doc.data();
list.push({
id: doc.id,
active,
name,
});
});
setTopics(list);
setLoading(false);
});
}, []);
const renderTopics = () =>{
return(
topics.map((item) =>{
return(
<CategoryTag key = {item.id}
color={userTopics.includes(item.name) ?"#51c0cc":"#303239"}
name = {item.name}
isSelected = {userTopics.includes(item.name)}
handleClick = {addTopicToUserTopicCollection}
/>
)
})
)
}
if(loading)
{
return (
<SafeAreaView style={{flex:1, backgroundColor:"#455a65"}}>
<View style={{width:200, padding:20, paddingTop:60}}>
<Text style ={{fontSize:25, fontWeight:"bold",
color:"#fff"}}>What are you</Text>
<Text style ={{fontSize:22, color:"#fff"}}>interested in?
</Text>
</View>
<View style={{flex:1, alignItems:"center",
justifyContent:"center", alignSelf:"center"}}>
<ActivityIndicator />
</View>
</SafeAreaView>
)
}
else // this never runs
{
return (
<SafeAreaView style={{flex:1, backgroundColor:"#455a65"}}>
<View>
<View style={{width:200, padding:20, paddingTop:60}}>
<Text style ={{fontSize:25, fontWeight:"bold",
color:"#fff"}}>What are you</Text>
<Text style ={{fontSize:22, color:"#fff"}}>interested in?
</Text>
</View>
<View style ={{flexDirection:"column", paddingTop:20}}>
<View style ={{padding:15, paddingTop:15,
marginBottom:15,
flexWrap:"wrap", flexDirection:"row"}}>
{renderTopics(topics)}
</View>
</View>
</View>
</SafeAreaView>
);
}
}
export default CategoryScreen;
You are immediately setting your setLoading state to false and therefore loading text might be rendering for fraction of second, or not at all, like a glitch. Try setting setLoading with a timeout and then you will see the intended behaviour.
const TestScreen= (props) => {
const [loading, setLoading ] = useState(true);
useEffect(() => {
setTimeout(()=>setLoading(false), 3000);
}, []);
if(loading)
{
return <Text>Hi</Text>;
}
else
{
return<Text>hey</Text>
}
}

Categories