Expo React Native: undefined is not an object (evaluating 'this.context.state') - reactjs

I am with undefined is not an object (evaluating 'this.context.state') error at my React Native application using Expo.
context/index.js
import React, { Component } from "react";
const MyContext = React.createContext();
class MyProvider extends Component {
state = {
stage: 1,
players:[],
result:''
}
render(){
return(
<>
<MyContext.Provider value={{ state:this.state }}>
{this.props.children}
</MyContext.Provider>
</>
)
}
}
export {
MyProvider, MyContext
}
App.js file:
import { StatusBar } from 'expo-status-bar';
import { Component } from 'react';
import { StyleSheet, Text, View, ScrollView } from 'react-native';
import { MyContext } from './src/context';
import { MainStage } from './src/components/main_stage'
import { UserStage } from './src/components/user_stage'
import { MyProvider } from './src/context';
class App extends Component {
static contextType = MyContext;
render() {
return (
<MyProvider>
<ScrollView>
<View style={styles.container}>
{
this.context.state.stage === 1 ?
<MainStage />
:
<UserStage />
}
</View>
</ScrollView>
</MyProvider>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default App
In this App.js i just want to show a different view if the stage value at state object is 1 or 2.
main_stage.js just in case:
import { Text, View } from 'react-native';
const MainStage = () => {
return (
<View>
<Text>This is the main stage.</Text>
</View>
);
}
export default MainStage;
user_stage.js is exactly equal, the difference is just the content at <Text>.
Hope you guys can help me!
I try this and this solution without success at all.

Related

react context in another screen

Good evening everyone,
I created two screens and I would like to pass the context to one of this screen but it doesn't work.
Here what I have so far :
App :
import React from 'react';
import { createAppContainer } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import HomeScreen from "./src/screens/HomeScreen";
import ExpenseScreen from "./src/screens/ExpenseScreen";
import BalanceScreen from "./src/screens/BalanceScreen";
import {ExpenseProvider} from "./src/context/ExpenseContext";
const navigator = createStackNavigator(
{
Home:HomeScreen,
Expense:ExpenseScreen,
Balance: BalanceScreen
},
{
initialRouteName:"Home",
defaultNavigationOptions:{
title:"App",
}
}
)
const App = createAppContainer(navigator);
export default () => {
return <ExpenseProvider>
<App/>
</ExpenseProvider>
};
HomeScreen:
import React from "react";
import { Text, StyleSheet, View, Button} from "react-native";
const HomeScreen = ({navigation}) => {
return(
<View>
<Text style={styles.text}>HomeScreen</Text>
{/*Shows default display*/}
<Button
onPress={()=> navigation.navigate('Expense')}
title="Expense Tracker"
/>
<Button
onPress={()=> navigation.navigate('Balance')}
title="Balance"
/>
</View>
)
};
const styles = StyleSheet.create({
text: {
fontSize: 30
}
});
export default HomeScreen;
Provider :
import React from 'react';
const ExpenseContext = React.createContext();
export const ExpenseProvider = ({children}) => {
const expensePosts = [
{title: 'Expense Post #1'},
{title: 'Expense Post #2'},
{title: 'Expense Post #3'}
]
return <ExpenseContext.Provider value={expensePosts}>{children}</ExpenseContext.Provider>
};
export default ExpenseContext;
Screen :
import React, {useContext} from "react";
import { Text, StyleSheet, View, Button, Flatlist } from "react-native";
import ExpenseContext from '../context/ExpenseContext';
const ExpenseScreen = () => {
const expensePosts = useContext(ExpenseContext)
return(
<View>
<Text style={styles.text}>Expense Tracker</Text>
<Flatlist
data={expensePosts}
keyExtractor={(expensePost) => expensePost.title}
renderItem={({item}) => {
return <Text>{item.title}</Text>
}}
/>
</View>
)
};
const styles = StyleSheet.create({
text: {
fontSize: 30
}
});
export default ExpenseScreen;
I am trying to import the context into the "expenseScreen" but it doesn't work.
The error message I have is " element type is invalid: expected a string or a class but got undefined. You likely forgot to export your component from the file it's defined in or you might have mixed up default and name imports. Check the render method of 'ExpenseScreen'".
What am I missing ?
Does the Expenseprovider exported in the App only applies for the 'homeScreen' ?
Thank you very much in advance and hope this is clear enough.

How to load custom Fonts in an Expo app using React Navigation and Redux

I just can not load custom fonts in an existing app using Expo, React Natvigation. I have an app that has Navigations set up in a core.js file as
import React from "react";
import {Text, View, StyleSheet} from "react-native";
import {NavigationContainer} from "#react-navigation/native";
import {createStackNavigator} from "#react-navigation/stack";
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import LoginScreen from "./login.js";
import RegisterScreen from "./register.js";
//import Home from "./home.js";
import PostAJobPage from "./secondTab.js";
import Ionicons from "react-native-vector-icons/Ionicons"
import store from "./store";
import SplashScreen from "./splashscreen";
import Home from "./homeStack.js";
import { Entypo } from '#expo/vector-icons';
import { MaterialCommunityIcons } from '#expo/vector-icons';
import SearchAJobStack from "./jobsearchstack.js";
const Tab = createBottomTabNavigator()
const Tabs = () => {
return(
//<NavigationContainer>
<Tab.Navigator initialRouteName = "home"
screenOptions = {({route}) => ({
tabBarIcon : ({focused,color, size}) => {
let iconName;
if(route.name == "home") {
iconName = "ios-home"
return <Ionicons name = {iconName} color = {color} size = {size}/>
}
else if(route.name == "postJob")
{
//iconName = "md-settings"
iconName = "briefcase"
return <Entypo name = {iconName} color = {color} size = {size}/>
}
else if (route.name == "searchJob")
{
iconName = "briefcase-search"
return <MaterialCommunityIcons name = {iconName} size={size} color= {color} />
}
//return <Ionicons name = {iconName} color = {color} size = {size}/>
}
})}
tabBarOptions = {{
style : {
height : 50
},
showLabel : false,
activeTintColor : "gold"
}
}>
<Tab.Screen name="home" component ={Home}/>
<Tab.Screen name="postJob" component ={PostAJobPage}/>
<Tab.Screen name="searchJob" component ={SearchAJobStack}/>
</Tab.Navigator>
//</NavigationContainer>
)
}
const Stack = createStackNavigator()
function Stacks() {
return(
<NavigationContainer>
<Stack.Navigator initialRouteName = "loadingPage">
<Stack.Screen
name = "loadingPage"
component = {SplashScreen}
options = {{
headerShown : false
}}/>
<Stack.Screen
name ="Main"
component = {Tabs}
options = {{
headerShown : false,
}}/>
<Stack.Screen name= "login"
component = {LoginScreen}
options = {{
title : "Login",
headerTitleAlign : "left"
}}/>
<Stack.Screen name= "register"
component = {RegisterScreen}
options = {{
title : "Register",
headerTitleAlign : "left",
}}/>
</Stack.Navigator>
</NavigationContainer>
)
}
export default class core extends React.Component {
render(){
return (
<Stacks/>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor : "#fff",
alignItems : "center",
justifyContent : "center",
}
})
I am importing this stacks in my App.js and have added the code to add custom fonts according to the Docs in Expo but if I change fontFamily: Pacifico to any of the screens it doesnot work
My app.js file is
import 'react-native-gesture-handler';
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import Core from "./core.js";
import {Provider} from "react-redux";
import store from "./store.js";
import * as Font from "expo-font";
const customFonts = {
dancingScript : require("./assets/fonts/DancingScript-Regular.ttf"),
Pacifico : require("./assets/fonts/Pacifico-Regular.ttf"),
Inter : require("./assets/fonts/Inter-VariableFont.ttf"),
}
export default class App extends React.Component {
state = {
fontsLoaded : false,
}
async _loadFontsAsync() {
await Font.loadAsync(customFonts);
this.setState({ fontsLoaded: true });
}
componentDidMount() {
this._loadFontsAsync();
}
render(){
if(this.state.fontsLoaded)
{
return (
<Provider store = {store}>
<Core/>
</Provider>
);
}
else {
return(
<View style= {styles.container}>
<Image source = {require("./ajax-loader.gif")}/>
</View>
)
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
//fontFamily : "dancingScript",
},
});
I personally feel this is a better way to load custom fonts. I use this method in all my projects. To loadFonts create a folder called hooks where your App.js is located
Then, Install expo-app-loading & expo-font
Then inside hooks folder create a file called useFonts.js
Inside useFonts.js write like this
import * as Font from "expo-font";
export default useFonts = async () => {
await Font.loadAsync({
"Pacifico" : require("./assets/fonts/Pacifico-Regular.ttf"),
// All other fonts here
});
};.
Now in your App.js write like this
import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import React, { useState } from 'react';
import useFonts from './hooks/useFonts';
export default function App() {
const [IsReady, SetIsReady] = useState(false);
const LoadFonts = async () => {
await useFonts();
};
if (!IsReady) {
return (
<AppLoading
startAsync={LoadFonts}
onFinish={() => SetIsReady(true)}
onError={() => {}}
/>
);
}
return <View styles={styles.container}>{/* Code Here */}</View>;
}
Note: The above solution was for Function components.
For Class Component, you can do something like this
Working Example Here
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import useFonts from './hooks/useFonts';
export default class App extends React.Component {
state = {
fontsLoaded: false,
};
async _loadFontsAsync() {
await useFonts();
this.setState({ fontsLoaded: true });
}
componentDidMount() {
this._loadFontsAsync();
}
render() {
if (this.state.fontsLoaded) {
return (
<View style={styles.container}>
<Text>Fonts Loaded</Text>
<Text style={{ fontFamily: 'Helvetica' }}>Helvetica Text</Text>
<Text>Normal Text</Text>
</View>
);
} else {
return (
<View style={styles.container}>
<Image
source={{
uri:
'https://landerapp.com/blog/wp-content/uploads/2018/06/1_FFP1bisztXseQFbZ-WQedw-1.png',
}}
style={{ width: '100%', height: '100%' }}
/>
</View>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
//fontFamily : "dancingScript",
},
});
this is how you can load your fonts in an expo app write the code in the entry point of your app which is mainly App.js
import { useFonts } from "expo-font";
const [fontsLoaded] = useFonts({
// Axiforma: require("./assets/fonts/Axiforma-Black.ttf"),
// BlackItalic: require("./assets/fonts/Axiforma-BlackItalic.ttf"),
Bold: require("./assets/fonts/Axiforma-Bold.ttf"),
// BoldItalic: require("./assets/fonts/Axiforma-BoldItalic.ttf"),
// Book: require("./assets/fonts/Axiforma-Book.ttf"),
// BookItalic: require("./assets/fonts/Axiforma-BookItalic.ttf"),
ExtraBold: require("./assets/fonts/Axiforma-ExtraBold.ttf"),
// ExtraBoldItalic: require("./assets/fonts/Axiforma-ExtraBoldItalic.ttf"),
// Heavy: require("./assets/fonts/Axiforma-Heavy.ttf"),
// HeavyItalic: require("./assets/fonts/Axiforma-HeavyItalic.ttf"),
// Italic: require("./assets/fonts/Axiforma-Italic.ttf"),
Light: require("./assets/fonts/Axiforma-Light.ttf"),
// LightItalic: require("./assets/fonts/Axiforma-LightItalic.ttf"),
Medium: require("./assets/fonts/Axiforma-Medium.ttf"),
// MediumItalic: require("./assets/fonts/Axiforma-MediumItalic.ttf"),
Regular: require("./assets/fonts/Axiforma-Regular.ttf"),
SemiBold: require("./assets/fonts/Axiforma-SemiBold.ttf"),
// SemiBoldItalic: require("./assets/fonts/Axiforma-SemiBoldItalic.ttf"),
Thin: require("./assets/fonts/Axiforma-Thin.ttf"),
// ThinItalic: require("./assets/fonts/Axiforma-ThinItalic.ttf"),
});
if (!fontsLoaded) return <AppLoading />;
Use #expo-google-fonts
Go to the project root from the terminal and type to install the font that wish, example:
expo install #expo-google-fonts/ubuntu
The explo cli will install all ubuntu fonts as a node module, look inside the path ./node_modules/#expo-google-fonts/ubuntu, all fonts are there.
Now, import the hook and the font styles that you wish from this font family, like this:
import { useFonts, Ubuntu_400Regular, Ubuntu_500Medium, Ubuntu_700Bold } from '#expo-google-fonts/ubuntu';
Then, load them inside your app using the hook:
let [fontsReady,fontsError] = useFonts({Ubuntu_400Regular, Ubuntu_500Medium, Ubuntu_700Bold});
fontsReady will be true when the fonts are ready to use and the fontsError will has the error reason if the app could not load the fonts.
To wait the fonts be ready, use expo-app-loading module and do something like this:
if (!fontsReady) return <AppLoading/>;
To choose the fonts that you wish to install on your project, visit https://directory.vercel.app/ , this will show all Google fonts and the import cmd in an easy way. Do not forget to include the useFonts hook.

How do create a stack screen with a class

I am coding an application that will have more than one page. I use '#react-navigation/native' and '#react-navigation/stack' to navigate between these pages. It works correctly when I write a function name in Stack.Screen's component. But I did not understand how the class call was made.
Api.js
import * as React from 'react';
import { StyleSheet, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import HomeScreen from './screens/HomeScreen';
const Stack = createStackNavigator();
export default function App(props) {
// Load any resources or data that we need prior to rendering the app
return (
<View style={styles.container}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Homa Page" component={HomeScreen}/>
</Stack.Navigator>
</NavigationContainer>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});
screens/HomeScreen.js
import * as React from 'react';
import { Text, View } from 'react-native';
import { getSummary } from '../data/getSummary.js';
export class HomeScreen extends Component {
constructor(props){
super(props);
this.state ={
isLoading: true,
}
this.getSummary = getSummary.bind(this)
}
componentDidMount(){
this.getSummary;
}
render(){
return (
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={ this.state.data}
keyExtractor={(item) => item.CountryCode}
renderItem={({ item }) => (
<View>
<Text>Country:{item.CountryCode}</Text>>
</View>
)}
/>
</View>
);
}
}

React native navigation error- navigating issue

I am trying to create react native application.But it is throwing error. I used react-native-navigation.
(I am trying to create react native application.But it is throwing error. I used react-native-navigation. )
import { createAppContainer, createSwitchNavigator } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import { createBottomTabNavigator } from "react-navigation-tabs";
import DashboardScreen from "./src/component/Dashboard";
import LoginScreen from "./src/component/Auth/Login";
import RegisterScreen from "./src/component/Auth/Register";
const AppStack = createStackNavigator({ Dashboard: DashboardScreen });
const AuthStack = createBottomTabNavigator({
SignIn: LoginScreen,
Register: RegisterScreen
});
export const RootNaviation = () => {
return createAppContainer(
createSwitchNavigator(
{
Auth: AuthStack,
App: AppStack
},
{ initialRouteName: "Auth" }
)
);
};
App File
import React from "react";
import { StyleSheet, Text, View, Button } from "react-native";
import { SwitchNavigator } from "./Router";
const Nav = SwitchNavigator();
export default function App() {
return (
<View style={styles.container}>
<Button title="dafdlka" />
<Nav />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center"
}
});
enter image description here
You have never created a variable called SwitchNavigator.
You can use RootNaviation
import { RootNaviation } from "./Router"
...
export default function App() {
return (
<View style={styles.container}>
<Button title="dafdlka" />
<RootNaviation />
</View>
);
}

React-Navigation is not working need perfect solution

I'm using React-Navigation with create react native app with expo sdk.
This is my my app.js page code:
import React from 'react';
import Expo from 'expo';
import { StyleSheet, Text, View } from 'react-native';
import { TabNavigator } from 'react-navigation';
import Home from './Components/Home';
import Settings from './Components/Settings';
class App extends React.Component {
render() {
const MainNavigation = TabNavigator({
Home: { screen: Home },
Settings: { screen: Settings },
});
return (
<View>
<MainNavigation />
</View>
);
}
}
export default App;
In app page i'm exporting two components name home and settings page
Home.js page code:
import React from 'react';
import { StyleSheet, View, Text, Platform } from'react-native';
class Home extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: 'Home',
headerStyle: {
marginTop: Platform.OS === 'android' ? 24 : 0
}
};
};
render () {
return (
<View>
<Text> Home Page </Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default Home;
and Setting.js page code is:
import React from 'react';
import { View, Text, Platform } from'react-native';
class Settings extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: 'Settings',
headerStyle: {
marginTop: Platform.OS === 'android' ? 24 : 0
}
};
};
render () {
return (
<View>
<Text> Settings Page </Text>
</View>
);
}
}
export default Settings;
My problem is that i'm trying to use tab navigator on my app with this two pages named Home.js and Settings.js
But it is not working and after expo sdk load its open with blank page (even no error returning)! Can anyone tell me what is my mistake on this codes or what is the issue that tab navigator is not coming or showing or working!!!!

Resources