My app closes when I press the switch screen button. I don't see any error output.
I did a version check and there was no problem.
The function I wrote for the button works
Router.js
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import First from "./First";
import Second from "./Second";
const Stack = createNativeStackNavigator();
const Router = () =>{
return(
<NavigationContainer>
<Stack.Navigator initialRouteName="First">
<Stack.Screen name="First" component={ First }/>
<Stack.Screen name="Second" component={ Second }/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default Router;
First.js
import React from 'react';
import {View,Text,Button} from 'react-native';
const First = ( props ) =>{
const gotoSecond = () => {
console.log("First");
props.navigation.navigate("Second");
console.log("second")
}
return (
<View>
<Text>Hello First Page!</Text>
<Button title="Go SecondPage!" onPress={gotoSecond}/>
</View>
);
};
export default First;
Second.js
import React from 'react';
import {View,Text} from 'react-native';
const Second = () =>{
return (
<View>
<Text>Hello Second Page!</Text>
</View>
);
};
export default Second;
OS:Android,
Emulator:Genymotion.
Now I'm using ADV instead of Genymotion, problem solved.
Related
I try to navigate between two pages in a React Native app. I keep getting errors for my implementations but I don't know why.
I have the following setup for a "Home" and "Settings" site in the React Native app with Navigator adjusted from the documentation:
App.js
import Home from "./Home";
import { NavigationContainer } from '#react-navigation/native';
export default function App() {
return <NavigationContainer><Home/></NavigationContainer>
}
Home.jsx
const Home = ({ navigation }) => {
return (
<View style={["some style...", {}]}>
<View style={["some style..."]}>
<TouchableOpacity onPress={() =>
navigation.navigate('Settings')}>
<Image "some image..."/>
</TouchableOpacity>
</View>
</View>
Settings.jsx
A component which should be rendered.
MyStack.jsx
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import Home from './Home';
import Settings from './Settings';
const Stack = createNativeStackNavigator();
const MyStack = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
/>
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
};
I get undefined is not an object (evaluating 'navigation.navigate'). Also adding this.props to navigation.navigate('Settings') throws and error. I am just not able to access my Navigator.
You seem to be setting up a navigator but never using it, since in App.js you are just calling <Home/>.
Change App.js to this:
import MyStack from "./MyStack"; // Use the correct path for the import
export default function App() {
return <MyStack/>
}
Add at the end of MyStack.jsx:
export default MyStack;
When the user presses the login button the Drawer.Navigation needs to change (I try to learn the basics so no form for the login needed). When I try to pass this action to App.js I get this Error:"TypeError: _this.props.loginState is not a function"
According to the errormessage the problem should be in this pice of code:
changeLoginState = () => {
this.props.loginState(true)
}
This is the code of App.js
import * as React from 'react';
import { getFocusedRouteNameFromRoute, NavigationContainer } from '#react-navigation/native';
import { createAppContainer } from "react-navigation";
import { RootNavigator } from './src/navigation/AppNavigator';
import { PropTypes } from 'react'
//navigation
import { createDrawerNavigator } from '#react-navigation/drawer'
import Account from './src/screens/account';
import Login from './src/screens/Login'
export default function App(){
let isLoggedIn = false
function changeLoginState(newState){
isLoggedIn = newState
}
const Drawer = createDrawerNavigator();
let d
let p
let l
if(isLoggedIn){
d = <Drawer.Screen name="Account" component={Account}/>
}else{
d = <Drawer.Screen name="Inloggen" component={Login} loginState={changeLoginState}/>
}
return(
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
{d}
</Drawer.Navigator>
</NavigationContainer>
)
}
And this is the code of Login comoponent: Login.js
import * as React from 'react';
import { Component } from 'react';
import { View, Button, StyleSheet, TouchableOpacity} from 'react-native';
class Login extends Component {
constructor(props){
super(props)
}
changeLoginState = () => {
this.props.loginState(true)
}
render(){
return (
<View style={{display: 'flex', justifyContent:'center', alignItems:'center', height: '100vh'}}>
<TouchableOpacity style={{backgroundColor: 'red'}} onPress={ () => this.changeLoginState() }>Login</TouchableOpacity>
</View>
);
}
}
export default Login
I have seen a lot of similar questions but nothing worked.
If you have other remarks on my code, feel free to comment.
I thank you.
Use options to pass props to screen:
options={{ loginState: changeLoginState }}
I want to navigate to List.js after I click the button in MainMenu.js file, but it always shows me this error:
TypeError: undefined is not an object (evaluating 'navigation.push')
This is my App.js file
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { List } from './List';
import { MainMenu } from './MainMenu';
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.js to stassrt working on your app!</Text>
<StatusBar style="auto" />
<MainMenu></MainMenu>
</View>
);
}
And this is my MainMenu.js file (I have the button in this file):
import React from 'react';
import { Text, Button, View, StyleSheet } from 'react-native';
import { ScreenContainer } from 'react-native-screens';
import { List } from './List';
import { useNavigation } from '#react-navigation/core';
export const MainMenu = ({navigation}) => (
<View>
<Text>Hello HOW ARE YsOU</Text>
<Button title="Click" onPress={() => navigation.push("List")}></Button>
</View>
);
In your MainMenu component, you are expecting an object with a key navigation as props. You are not passing any props to the MainMenu, however, and so the props are undefined, but you are expecting an object. To fix this, change the component to:
import React from 'react';
import { Text, Button, View, StyleSheet } from 'react-native';
import { ScreenContainer } from 'react-native-screens';
import { List } from './List';
import { useNavigation } from '#react-navigation/core';
export const MainMenu = () => {
const navigation = useNavigation()
return (
<View>
<Text>Hello HOW ARE YsOU</Text>
<Button title="Click" onPress={() => navigation.push("List")}>
</Button>
</View>
);
};
We are using the hook, instead of props.
I don't know how you implemented the stack navigator, but I think your App.js file should look like this:
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { List } from './List';
import { MainMenu } from './MainMenu';
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<>
<Stack.Screen name="Main Menu" component={MainMenu} />
<Stack.Screen name="List" component={List} />
</>
</Stack.Navigator>
</NavigationContainer>
);
}
And I think your MainMenu component should look like this:
import React from 'react';
import { Text, Button, View, StyleSheet } from 'react-native';
import { ScreenContainer } from 'react-native-screens';
import { List } from './List';
export const MainMenu = ({navigation}) => (
<View style={styles.container}>
<Text>Open up App.js to stassrt working on your app!</Text>
<StatusBar style="auto" />
<View>
<Text>Hello HOW ARE YsOU</Text>
<Button title="Click" onPress={() => navigation.navigate("List")</Button>
</View>
</View>
I want the app to check if there's a user logged in (firebase authentication). If there is, navigate to one page (react navigation v5), if there isn't, to another.
I have the following code:
In App.js
//import navigation + screens
const Stack = createStackNavigator();
const MaterialBottomTabs = createMaterialBottomTabNavigator();
class App extends React.Component {
AuthStack = () => {
<Stack.Navigator>
<Stack.Screen name="login" component={LoginScreen} />
<Stack.Screen name="register" component={RegisterScreen} />
</Stack.Navigator>
}
createBottomTabs = () => {
return <MaterialBottomTabs.Navigator>
<MaterialBottomTabs.Screen name="first" component={firstScreen} />
<MaterialBottomTabs.Screen name="second" component={secondScreen} />
</MaterialBottomTabs.Navigator>
}
render(){
return(
<LoadingScreen />
)
}
}
export default App;
In Loading.js
import React from "react";
import { Text, SafeAreaView } from "react-native";
import * as firebase from "firebase";
import {AuthStack, createBottomTabs} from "./App.js";
class LoadingScreen extends React.Component {
componentDidMount() {
firebase.auth().onAuthStateChanged((user) => {
this.props.navigation.navigate(user ? createBottomTabs : AuthStack);
});
}
render() {
return (
<SafeAreaView>
<Text>
Waiting...
</Text>
</SafeAreaView>
);
}
}
export default LoadingScreen;
I get an error which says:
TypeError: undefined is not an object (evaluating '_this.props.navigation.navigate')
The navigation prop is not passed into all components, only screen components receive this prop automatically! If, however, you wish to access the navigation prop in any of your components, you may use the useNavigation hook.
Here is an example from the docs
import * as React from 'react';
import { Button } from 'react-native';
import { useNavigation } from '#react-navigation/native';
function MyBackButton() {
const navigation = useNavigation();
return (
<Button
title="Back"
onPress={() => {
navigation.goBack();
}}
/>
);
}
I am building an app in which several of the screens have dynamically rendered cards that are mapped to an array of objects called ENTRIES. Each one of these cards can be pressed to navigate to a corresponding screen, however, I cannot seem to get the navigation to work.
I am passing is the screen value from ENTRIES as props from the Settings.js screen into the ClickableCard component, which then gets passed into the TouchableOpacity onClick as this.props.navigation.navigate(screen).
However I keep getting the following error TypeError: undefined is not an object (evaluating '_this3.props.navigation.navigate')
Here is an example of the code below:
App.js File
import React from 'react;
import {createMaterialBottomTabNavigator} from '#react-navigation/material-bottom-tabs';
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import Home from './src/screens/Home';
import SettingsScreen from './src/screens/SettingsScreen';
import PrivacyScreen from './src/screens/PrivacyScreen';
import NotificationsScreen from './src/screens/NotificationsScreen';
import SoundsScreen from './src/screens/SoundsScreen';
import ThemeScreen from './src/screens/ThemeScreen';
const PrivacyStack = createStackNavigator();
const SettingsStack = createStackNavigator();
const AuthStack = createStackNavigator();
const MainStack = createStackNavigator();
const Tabs = createMaterialBottomTabNavigator();
const TabNavigator = () => {
return (
<Tabs.Navigator
initialRouteName="Home"
<Tabs.Screen
name="Home"
component={HomeStack}
/>
Tabs.Screen
name="Settings"
component={SettingsStack}
children={this.SettingsStack}
</Tabs.Navigator>
)
}
const AuthStack = () => (
<AuthStack.Navigator>
<AuthStack.Screen
name="Auth"
component={Auth}
/>
</AuthStack.Navigator>
);
const SettingsStackScreen = () => (
<SettingsStack.Navigator>
<SettingsStack.Screen
name="Settings"
component={Settings}
/>
<SettingsStack.Screen
name="Privacy"
component={PrivacyStack}
/>
<SettingsStack.Screen
name="Theme"
component={ThemeScreen}
/>
<SettingsStack.Screen
name="Notifications"
component={NotificationsScreen}
/>
<SettingsStack.Screen
name="Sound"
component={SoundsScreen}
/>
</SettingsStack.Navigator>
);
const PrivacyStack = () => (
<PrivacyStack.Navigator>
<PrivacyStack.Screen
name="Privacy"
component={PrivacyScreen}
/>
<PrivacyStack.Screen
name="Notifications"
component={NotificationsScreen}
/>
</PrivacyStack.Navigator>
);
const App = () => {
return (
<NavigationContainer ref={navigationRef}>
<MainStack.Navigator>
<MainStack.Screen name="Tabs" component={TabNavigator} />
<MainStack.Screen
name="Auth"
component={AuthStack}
options={{gestureEnabled: false}}
/>
</MainStack.Navigator>
</NavigationContainer>
)
}
Settings.js File
import React, {Component} from 'react';
import {TouchableOpacity, ScrollView} from 'react-native;
import ClickableCard from './ClickableCard'
export default class Settings extends Component {
render(screen, index) {
return (
<ScrollView>
{ENTRIES.map((entry, index) => (
<ClickableCard screen={entry.screen} key={entry.index}/>
))}
</ScrollView>
)
}
export default Settings
ClickableCard.js Component
import React, {Component} from 'react';
import {TouchableOpacity, ScrollView} from 'react-native;
export default class ClickableCard extends Component {
constructor(props) {
super(props);
}
render() {
const {
screen,
key
} = this.props
return (
<TouchableOpacity
key={key}
onPress={() => this.props.navigation.navigate(screen)}>
</TouchableOpacity>
)
}
}
entries.js File
import React from 'react';
export const ENTRIES = [
{
name: "Theme",
screen: "ThemeScreen",
},
{
name: "Sounds",
screen: "SoundsScreen",
},
{
name: "Notifications",
screen: "NotificationsScreen",
},
]
You are trying to access navigation outside the navigation stack.
If you are using a functional component you can go with the useNavigation hook but as this is a class based component you will have to send the navigation as a prop or you can do the below as suggested in the documentation
import { useNavigation } from '#react-navigation/native';
class ClickableCard extends Component {
constructor(props) {
super(props);
}
render() {
const { screen, key } = this.props;
return (
<TouchableOpacity
key={key}
onPress={() =>
this.props.navigation.navigate(screen)
}></TouchableOpacity>
);
}
}
const ClickableCardWithNavigation= (props) {
const navigation = useNavigation();
return <ClickableCard {...props} navigation={navigation} />;
}
export default connect(ClickableCardWithNavigation)(TodoList)