Expo app crashing on android on rendering components - reactjs

When i render a screen in App.js the app crashes on android but works fine on android. If i render some function defined in App.js in renders on screen.
App.js
import React from 'react';
import {enableScreens} from 'react-native-screens';
enableScreens();
import { ActivityIndicator, View, Text, Button, TextInput, StyleSheet, TouchableOpacity } from "react-native";
import { NavigationContainer } from "#react-navigation/native";
import {createNativeStackNavigator} from "#react-navigation/native-stack";
import Main from "./screens/Main"
function HomeScreen({navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<TouchableOpacity onPress={() => {navigation.navigate("LoginPage")}}>
<Text>NEXT</Text>
</TouchableOpacity>
</View>
);
}
function S1({navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<TouchableOpacity onPress={() => {navigation.navigate("main")}}>
<Text>NEXT</Text>
</TouchableOpacity>
</View>
);
}
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" options={{headerShown : false}} component={HomeScreen} />
<Stack.Screen name="LoginPage" options={{headerShown : false}} component={S1} />
<Stack.Screen name="main" options={{headerShown : false}} component={Main} />
</Stack.Navigator>
</NavigationContainer>
);
}
Main.js
import react, {useState} from "react";
import { View, Text, Button, TextInput, StyleSheet, TouchableOpacity } from "react-native";
export default function Main({navigation}){
const options = [
{
name: "Games",
redirect: "Games"
},
{
name : "AR Tutorials",
redirect: "AR"
},
{
name : "Competition",
redirect : "Competition"
}
];
return(
<View style={styles.container}
>
{
options.map(op => (
<TouchableOpacity
style={styles.card}key={op.name} onPress={() => {navigation.navigate(op.redirect)}}>
<Text style={styles.cardText}>{op.name}</Text>
</TouchableOpacity>
))
}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
card: {
backgroundColor: "rgb(0, 100, 255)",
minHeight: "25%",
minWidth: "70%",
borderRadius: 1,
marginVertical: "1rem",
display: "flex",
justifyContent: "flex-end",
alignItems: "center"
},
cardText : {
marginBottom: "0.5rem"
}
});
Here functions HomeScreen and S1 renders but on navigating to Main the app crashes whiteout any logs.
I have tried building apk ind then running but it shows same behaviour.

Related

I want to pass data to another screen by FlatList in react native

Hello guys am new on react native I want to build an app like news app with posts,I stack in how to pass the data in flatlist to another screen to open the screen with the post data i use V6 navigation Note I do the Navigation and the post touchable this is my code :
the import :
import { StyleSheet, Text, View ,Button ,FlatList,TouchableOpacity } from 'react-native';
import React,{useState} from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
Screen one :
function HomeScreen({navigation}) {
const [news,setnews]=useState([
{title:'React Native students can get the basic knowledge',by:'Chris brown',dateTime:'15 may',key:'1'},
{title:'whats happening here is that you are trying to',by:'charley',dateTime:'15 jan',key:'2'},
{title:'statuses. specifically, you have to look here:',by:'yami',dateTime:'15 jon',key:'3'},
{title:'screen you want to show, when the authentication status changes.',by:'maria',dateTime:'15 nov',key:'4'},
]);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<FlatList
data={news}
renderItem={({item})=>(
<TouchableOpacity onPress={()=>navigation.navigate('Detials' ,item)}>
<Text style={{fontSize:15,}}>{item.title}</Text>
</TouchableOpacity>
)}
/>
</View>
);
}
screen two:
function DetialsScreen({navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>{navigation.getParam('title')}</Text>
</View>
);
}
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Detials" component={DetialsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
screenone :
<FlatList
data={news}
renderItem={({item})=>(
<TouchableOpacity onPress={()=> this.props.navigation.navigate('ScreenTwo' , item)}>
<Text style={{fontSize:15,}}>{item.title}</Text>
</TouchableOpacity>
)}
/>
at screentwo you can get using this.props.route.params
export default class ScreenTwo extends Component {
constructor(props, ctx) {
super(props, ctx);
this.state = {
news: this.props.route.params
};
}
render() {
const news = this.state.news
return (
<View style={{flex: 1, margin: 30}}>
<Text>Title is : {news.title}{'\n'}{'\n'}by {news.by}</Text>
<Button
style={{marginTop: 20}}
onPress={() => this.props.navigation.goBack()}
title="Back"
color="#841584"
/>
</View>
);
}
}
for snack you can try here : https://snack.expo.dev/#edoofx/example1111
im using class anyway :D

ReactNavigation 5.0 browser next/previous button not enable

I have created a project using React Native for Web and it is working fine in mobile but when I run into the web it does not enable the browser default next-previous button.
How to enable browser button and manage next previous in browser
// In App.js in a new project
import * as React from 'react';
import { View, Text,Button,Platform } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
const isWeb = Platform.OS === 'web';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => linkTo('/Details')} title="Go to Details Screen" />
</View>
);
}
function Details() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontWeight:'100',fontSize:30}}>Detail's Screen</Text>
</View>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="HomeScreen">
<Stack.Screen name="HomeScreen" component={HomeScreen} options={{ headerShown: !isWeb}} />
<Stack.Screen name="Setting" component={Setting} options={{headerShown:!isWeb}}/>
<Stack.Screen name="Details" component={Details} options={{headerShown:!isWeb}}/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
I think you have to use "navigation" object that is part of the params to the Home Screen. Have a look at below code
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => navigation.navigate('Details');} />
</View>
);
}

React-navigation change url but not view

I am using React Native for Web and implemented navigation in my app but I am not able to navigate next - previous with browser button,
The URL is changed in the address bar of the browser but not able to change the view.
I have used React-Navigation for both Web/Mobile, Anyone knows a better approach please guide me
//App.js
import * as React from 'react';
import { View, Text,Button,Platform } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<View style={{ marginVertical: 20 }}>
<Text style={{fontWeight:'100',fontSize:30}}>Home Screen</Text>
</View>
<Button
title="Go to Details Screen"
onPress={() => navigation.navigate('Details')}
/>
<View style={ {marginVertical:20}}>
<Button title="Go to Setting Screen" onPress={() => navigation.navigate('Setting')} />
</View>
</View>
);
}
const Stack = createStackNavigator();
function App() {
const linking = {
prefixes: ['myurlhere://'],
config: {
screens: {
Setting: 'Setting',
Details: 'Details',
},
},
};
return (
<NavigationContainer linking={linking} >
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} options={{ headerShown: !isWeb, headerLeft:()=> null }} />
<Stack.Screen name="Setting" component={Setting} options={{headerShown:!isWeb}}/>
<Stack.Screen name="Details" component={Details} options={{headerShown:!isWeb}}/>
</Stack.Navigator>
</NavigationContainer>
);
}
[![//Setting Screen
function Setting() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontWeight:'100',fontSize:30}}>Setting Screen</Text>
</View>
);
}
//Details Screen
function Details() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontWeight:'100',fontSize:30}}>Detail's Screen</Text>
</View>
);
}]
export default App;
I am also looking into it.
But here is where I am at and its working.
const linking = {
prefixes: ['http://localhost:19006/', 'mychat://'],
config: {
screens: {
Home: '',
Search: '?:id/Search',
}
},
};
return (
<AppContext.Provider value={userSettings}>
<NavigationContainer linking={linking}>
<StackContainer />
</NavigationContainer>
</AppContext.Provider>
);

React Navigation Shared Element 5 Nested Navigators

I'm running into a little issue with react-navigation-shared-element 5, so I made a very basic app to show an example. Basically I have a tab navigator nested in a stack navigator and when navigating to the tab navigator I'd like for a shared element transition. This is what I have so far. The transition was working when I had both MainScreen and OtherScreen in the Stack Navigator, but when I moved OtherScreen to the tab navigator it stopped.
import {NavigationContainer} from '#react-navigation/native';
import MainScreen from './src/MainScreen';
import OtherScreen from './src/OtherScreen';
import OtherScreenSecond from './src/OtherScreenSecond';
import {createSharedElementStackNavigator} from 'react-navigation-shared-element';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
const Stack = createSharedElementStackNavigator();
const Tab = createBottomTabNavigator();
const TabStuff = () => {
return (
<Tab.Navigator>
<Tab.Screen name="OtherScreen" component={OtherScreen} />
<Tab.Screen name="OtherScreenSecond" component={OtherScreenSecond} />
</Tab.Navigator>
);
};
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator mode="modal" headerMode="none">
<Stack.Screen name="MainScreen" component={MainScreen} />
<Stack.Screen name="Tabs" component={TabStuff} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
import {View, Text, StyleSheet, TouchableOpacity} from 'react-native';
import {SharedElement} from 'react-navigation-shared-element';
const MainScreen = (props) => {
return (
<View style={{...styles.container}}>
<SharedElement id="test">
<View
style={{
width: 100,
height: 100,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 50,
backgroundColor: 'orange',
marginBottom: 50,
}}></View>
</SharedElement>
<TouchableOpacity onPress={() => props.navigation.navigate('Tabs')}>
<Text>Next</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'red',
},
});
export default MainScreen;
import {View, Text, StyleSheet, TouchableOpacity} from 'react-native';
import {SharedElement} from 'react-navigation-shared-element';
const OtherScreen = (props) => {
return (
<View style={{...styles.container}}>
<SharedElement id="test">
<View
style={{
width: 150,
height: 150,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 75,
backgroundColor: 'blue',
marginBottom: 50,
}}></View>
</SharedElement>
<TouchableOpacity onPress={() => props.navigation.pop()}>
<Text>Back</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'yellow',
},
});
OtherScreen.sharedElements = (route, otherRoute, showing) => {
return ['test'];
};
export default OtherScreen;
Any pointers would be greatly appreciated, thanks!
You have to add sharedElementsConfig to Stack. Screen specifying the id of the shared element to work while navigating back
Change code to:
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator mode="modal" headerMode="none">
<Stack.Screen
name="MainScreen"
sharedElementsConfig={(props) => [
{
id: 'test', animation: 'fade'
}
]}
component={MainScreen} />
<Stack.Screen name="Tabs" component={TabStuff} />
</Stack.Navigator>
</NavigationContainer>
);
};

Passing username and family name from google login

I've managed to set up Google login using 'expo-google-app-auth'.
This is my Login.js, which handles the login page and the google login details and logic:
import React, { Component } from 'react'
import {Text,
View,
StyleSheet,
Image,
Alert} from 'react-native'
import { TouchableOpacity } from 'react-native-gesture-handler';
import { Provider as PaperProvider,
Button,
Caption} from 'react-native-paper'
import { createStackNavigator } from '#react-navigation/stack'
import { NavigationContainer } from '#react-navigation/native';
import MyDrawer from '../navigation/Drawer'
import QR from './QR'
const Stack = createStackNavigator();
import * as Google from 'expo-google-app-auth';
const IOS_CLIENT_ID =
"your-ios-client-id";
const ANDROID_CLIENT_ID =
"my-android-id";
class Login extends Component {
signInWithGoogle = async () => {
try {
const result = await Google.logInAsync({
iosClientId: IOS_CLIENT_ID,
androidClientId: ANDROID_CLIENT_ID,
scopes: ["profile", "email"]
});
if (result.type === "success") {
console.log("LoginScreen.js.js 21 | ", result.user.givenName, result.user.familyName, result.user.email, result.user.photoUrl);
this.props.navigation.navigate("MyDrawer", {
username: result.user.givenName,
lastname: result.user.familyName,
email: result.user.email,
photoUrl: result.user.photoUrl
}); //after Google login redirect to MyDrawer
return result.accessToken;
} else {
return { cancelled: true };
}
} catch (e) {
console.log('LoginScreen.js.js 30 | Error with login', e);
return { error: true };
}
};
render(){
return (
<PaperProvider>
<View style={styles.container}>
<View style={styles.imageCon}>
<Image
source={require('../img/logo-krug.png')}></Image>
</View>
<View style={styles.textCon}>
<Text style={styles.text}> Dobrodošli u eSTUDENT mobilnu aplikaciju!</Text>
</View>
<View style={styles.buttonCon}>
<Button
icon='camera'
mode='outlined'
onPress={this.signInWithGoogle}
>
google
</Button>
</View>
</View>
</PaperProvider>
)
}
}
export default function LoginStack() {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName='Login'
screenOptions={{
headerShown: false
}}>
<Stack.Screen name='MyDrawer' component={MyDrawer} />
<Stack.Screen name='Login' component={Login} />
</Stack.Navigator>
</NavigationContainer>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ecf0f1'
},
imageCon: {
height: '35%',
width: '100%',
justifyContent: "center",
alignItems: "center"
},
textCon:{
height:'20%',
alignItems: 'center',
justifyContent: 'center'
},
text: {
textAlign: "center",
fontSize: 20,
fontWeight: 'bold'
},
buttonCon:{
height: '30%',
justifyContent:'center',
alignItems: 'center'
},
});
And I want to pass the username, family name, email and profile picture to these 2 files.
Drawer.js, which handles the side Drawer and navigation:
import React from 'react'
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
import { Ionicons, MaterialIcons, Feather } from '#expo/vector-icons';
import { ScrollView,
TouchableOpacity,
Text,
View,
Image,
StatusBar,
StyleSheet,
} from 'react-native'
import QR from '../screens/QR';
import Odabir from '../screens/Odabir'
import { SafeAreaView } from 'react-navigation';
import { Divider } from 'react-native-paper'
const Drawer = createDrawerNavigator();
function CustomDrawerContent(props) {
return(
<SafeAreaView style={{flex:1}}>
<View style={{height: 150, alignItems: 'center', justifyContent: 'center', marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight}}>
<Image source={require('../img/account.png')}
style={{height: 120, width: 120, borderRadius: 60}}
/>
</View>
<View style={{height: 50, alignItems:'center'}}>
<Text style={styles.naslov}> This is where I want to pass the username and last name </Text>
</View>
<Divider />
<ScrollView style={{marginLeft: 5,}}>
<TouchableOpacity
style={{marginTop: 20, marginLeft: 20}}
onPress={() => props.navigation.navigate('QR')}
>
<View style={{padding:10}}>
<Ionicons name='ios-qr-scanner' size={20} styles={{}}>
<Text style={styles.naslov}> QR</Text>
</Ionicons>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{marginTop: 20, marginLeft: 20}}
onPress={() => props.navigation.navigate('Odabir')}
>
<View style={{padding:10}}>
<Ionicons name='ios-qr-scanner' size={20} styles={{}}>
<Text style={styles.naslov}> Odabir</Text>
</Ionicons>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{marginTop: 20, marginLeft: 20}}
onPress={() => props.navigation.navigate('Odabir')}
>
<View style={{padding:10}}>
<Ionicons name='ios-qr-scanner' size={20} styles={{}}>
<Text style={styles.naslov}> Odabir</Text>
</Ionicons>
</View>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
)
}
export default function MyDrawer() {
return (
<NavigationContainer independent={true}>
<Drawer.Navigator initialRouteName='QR' drawerContent={props => CustomDrawerContent(props)}>
<Drawer.Screen
name="QR"
component={QR}
/>
<Drawer.Screen
name="Odabir"
component={Odabir}
/>
</Drawer.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
naslov: {
fontSize: 20,
},
})
and finally QR.js, which holds some basic information and I'd like to personalize it a bit since it's the 'Home' page users land on
import React, { Component } from 'react'
import {Text,
SafeAreaView,
View,
StyleSheet,
Image
} from 'react-native'
import Header from '../navigation/Header'
export default function QR({navigation}) {
return (
<SafeAreaView style={styles.container}>
<Header title='Moj QR' isHome={true} navigation={navigation}/>
<View style={styles.qrCon}>
<Image
style={styles.qr}
source={require('../img/QR_code_for_mobile_English_Wikipedia.svg.png')}
/>
</View>
<View style={styles.textCon}>
<Text style={styles.text}>This is where I want to pass the username and last name</Text>
<Text style={styles.text}>Ovo je tvoj QR kod</Text>
</View>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ecf0f1',
alignItems: 'center',
},
qrCon:{
width: '60%',
height: '60%',
alignItems: 'center',
justifyContent: 'center',
},
qr: {
width: '120%',
height: '120%',
resizeMode: 'contain'
},
textCon: {
height: '7%'
},
text:{
fontSize: 35,
fontWeight: '600'
},
buttonCon:{
height: '15%',
justifyContent:'center',
alignItems: 'center'
}
})
The example I'm following used {this.props.navigation.getParam("username")} but that isn't working for me. How would I exactly pass the data?
I had this issue recently. React navigation 5 doesn't support props.navigation.getParam instead you can use this.props.route.params to access the data you passed in your navigation prop. So to access the username you can use this.props.route.params.username;
The way to solve this, at least passing data to the Drawer.js component is to rewrite the code like this:
if (result.type === "success") {
console.log("LoginScreen.js.js 21 | ", result.user.givenName, result.user.familyName, result.user.email, result.user.photoUrl);
this.props.navigation.navigate("MyDrawer",
username = result.user.givenName,
lastname = result.user.familyName,
email = result.user.email,
photoUrl = result.user.photoUrl);
return result.accessToken;
;
Then just putting that as a variable in Drawer.js
<View style={{height: 30, alignItems:'center'}}>
<Text style={styles.naslov}>{username} {lastname}</Text>
</View>

Resources