cannot read property navigate of undefined - react-native

I am getting this error cannot read the property of navigate when try to navigate to the SignInScreen
this is the splash screen that have created
import React from 'react';
import {
View,
Text,
TouchableOpacity,
Dimensions,
StyleSheet,
StatusBar,
Image
} from 'react-native';
import * as Animatable from 'react-native-animatable';
import LinearGradient from 'react-native-linear-gradient';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { useTheme } from '#react-navigation/native';
const SplashScreen = ({navigation}) => {
const { colors } = useTheme();
return (
<View style={styles.container}>
<StatusBar backgroundColor='#009387' barStyle="light-content"/>
<View style={styles.header}>
<Animatable.Image
animation="bounceIn"
duraton="1500"
source={require('../assets/logo.png')}
style={styles.logo}
resizeMode="stretch"
/>
</View>
<Animatable.View
style={[styles.footer, {
backgroundColor: colors.background
}]}
animation="fadeInUpBig"
>
<Text style={[styles.title, {
color: colors.text
}]}>Stay connected with everyone!</Text>
<Text style={styles.text}>Sign in with account</Text>
<View style={styles.button}>
<TouchableOpacity onPress={()=>navigation.navigate('SignInScreen')}>
<LinearGradient
colors={['#08d4c4', '#01ab9d']}
style={styles.signIn}
>
<Text style={styles.textSign}>Get Started</Text>
<MaterialIcons
name="navigate-next"
color="#fff"
size={20}
/>
</LinearGradient>
</TouchableOpacity>
</View>
</Animatable.View>
</View>
);
};
export default SplashScreen;
this is the main App.js FILE WHICH IS THE ROOT FILE
const Drawer = createDrawerNavigator();
// const [isEnabled, setIsEnabled] = React.useState(false);
export default function App() {
return (
<PaperProvider theme={PaperDarkTheme}>
<SplashScreen />
</PaperProvider>
);
}

Looks like you missed to wrap main Navigation container and then drawer this can work :
import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
const Drawer = createDrawerNavigator();
// const [isEnabled, setIsEnabled] = React.useState(false);
export default function App() {
return (
<PaperProvider theme={PaperDarkTheme}>
<NavigationContainer>
<Drawer.Navigator initialRouteName="splash">
<Drawer.Screen name="splash" component={SplashScreen } />
{// other Screens}
</Drawer.Navigator>
</NavigationContainer>
</PaperProvider>
);
}

Related

The action 'NAVIGATE' with payload {"name":"AddTask"} was not handled by any navigator. Do you have a screen named 'AddTask'?

App.js
import React from'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator, Header } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import Todo from './Todo';
import Done from './Done';
import Entrypage from './Entrypage';
import Addtask from './Addtask';
import Fontawesome5 from 'react-native-vector-icons/FontAwesome5';
import { StatusBar } from 'react-native';
const Tab = createBottomTabNavigator();
const Hometabs = () => {
return(
<NavigationContainer
independent={true}
>
<Tab.Navigator
screenOptions={({route})=>({
tabBarActiveTintColor:('#4682b4'),
tabBarLabelStyle:{fontSize:13,fontWeight:'bold'},
tabBarIcon:({focused,size,color,}) =>{
let iconname;
if(route.name==='To-do'){
iconname='clipboard-list';
color=focused? '#383':'#555';
size=focused? 26 : 25;
}else if(route.name==='Done'){
iconname='clipboard-check';
color=focused? '#383':'#555';
size=focused? 26 : 25;
}
return(
<Fontawesome5
name={iconname}
color={color}
size={size}
/>
)
}
})}
>
<Tab.Screen
name="To-do"
component={Todo}
options={{header:() => null}}
/>
<Tab.Screen
name="Done"
component={Done}
options={{header:() => null}}
/>
</Tab.Navigator>
</NavigationContainer>
)
}
const RootStack = createStackNavigator();
const App = () =>{
return(
<NavigationContainer>
<RootStack.Navigator
initialRouteName="Entry"
>
<RootStack.Screen
name="Entry"
component={Entrypage}
options={{
header:() => null
}}
/>
<RootStack.Screen
name="Tasks"
component={Hometabs}
options={{headerStyle:{backgroundColor:'#4682b4'},
headerTintColor:'#fff',
headerTitleAlign:'center',
}}
/>
<RootStack.Screen
name="AddTask"
component={Addtask}
/>
</RootStack.Navigator>
</NavigationContainer>
)
}
export default App;
Entrypage:
import React, { useEffect } from 'react';
import{
View,
Text,
Image,
StyleSheet,
StatusBar,
}from 'react-native';
export default function Enrtypage({navigation}) {
useEffect(()=>{
setTimeout(()=>{
navigation.replace('Tasks');
},2000);
},[]);
return(
<View style={styles.body}>
<StatusBar
backgroundColor={'#4682b4'}
/>
<Image
style={styles.logo}
source={require('../assests/write.png')}
/>
<Text style={styles.Text}>
To-Do List
</Text>
</View>
)
}
const styles = StyleSheet.create({
body:{
flex:1,
backgroundColor:'#4682b4',
alignItems:'center',
justifyContent:'center',
},
Text:{
fontSize: 35,
fontWeight:'900',
margin:15,
color:'#fff'
},
logo:{
height:150,
width: 150,
},
})
Todo:
import React from 'react';
import{
View,
Text,
StyleSheet,
TouchableOpacity,
Button,
}from 'react-native';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
export default function Todo ({navigation}) {
return(
<View style={styles.body}>
<TouchableOpacity style={styles.button}
onPress={()=>{
navigation.navigate('AddTask');
}}
>
<FontAwesome5
name='pen'
color='#fff'
size={23}
/>
</TouchableOpacity>
</View>
)
}
const styles = StyleSheet.create({
body:{
flex:1,
},
text:{
color:'#000',
},
button:{
width:60,
height:60,
backgroundColor:'#4682b4',
borderRadius: 50,
borderColor:'#000',
justifyContent:'center',
alignItems:'center',
position:'absolute',
bottom:20,
right: 20,
},
})
Done:
import React from 'react';
import{
View,
Text,
StyleSheet,
}from 'react-native';
export default function Done () {
return(
<View style={styles.body}>
<Text style={styles.text}>
Done
</Text>
</View>
)
}
const styles = StyleSheet.create({
body:{
flex:1,
},
text:{
color:'#000',
}
})
Addtask:
import React from 'react';
import{
View,
StyleSheet,
} from 'react-native';
import { TextInput } from 'react-native-gesture-handler';
export default function Addtask () {
return(
<View>
<TextInput/>
</View>
)
}
const style=StyleSheet.create({
body:{
flex:1,
},
})
The Button in Todo is not navigating to Addtask page.

Why can I not navigate to another page from FlatList component in react native?

I'm not sure what's wrong here, as far as I can tell I am doing this correctly as it has worked everywhere else in my app. The only difference is that I'm trying to do this from a FlatList component. What is wrong with this? I've also tried putting {navigation} in renderMyItem instead of FLToyCard brackets, didn't work either. Error I'm getting is:
TypeError: undefined is not an object (evaluating 'navigation.navigate').
import { StyleSheet, Text, View, FlatList } from 'react-native'
import React from 'react'
import Toy from './Database'
import ToyCard from './ToyCard'
const FLToyCard = ({navigation}) => {
const headerComp = () => {
return(
<View style={{alignSelf: 'center'}}>
<Text style={{fontSize: 25, padding: 10}}>All Toys For Sale</Text>
</View>
)
}
const renderMyItem = ({item}) => {
return(
<View style={{flex: 1}}>
<ToyCard
name={item.name}
image={item.image}
price={item.price}
desc={item.desc}
seller={item.seller}
onPress={()=>navigation.navigate('SlugProduct')}
/>
</View>
)
}
return(
<View>
<FlatList
data={Toy}
renderItem={renderMyItem}
keyExtractor={(item)=>item.id}
numColumns={2}
ListHeaderComponent={headerComp}
/>
</View>
)
}
export default FLToyCard
This is my App.js:
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native'
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import SlugProduct from './Screens/SlugProduct';
export default function App() {
const Stack = createNativeStackNavigator()
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='Login' >
// list of other pages
<Stack.Screen name="SlugProduct" component={SlugProduct} />
<Stack.Screen name='ViewToys' component={ViewToys}
</Stack.Navigator>
</NavigationContainer>
);
}
EDIT: heres the ViewToys page that FLToyCard is being input into. I've tried adding the onPress into both Views and FLToyCard but got the same error each time.
import { StyleSheet, Text, View, ScrollView} from 'react-native'
import React from 'react'
import FLToyCard from '../Components/FlatListCards'
const ViewToys = ({navigation}) => {
return (
<View style={{backgroundColor: '#ffce20', height: '100%'}}>
<View>
<FLToyCard />
</View>
</View>
)
}
export default ViewToys
The issue is that your not passing navigation props from screen ViewToys into component FLToyCard.
Try this
In ViewToys Screen:
import { StyleSheet, Text, View, ScrollView} from 'react-native'
import React from 'react'
import FLToyCard from '../Components/FlatListCards'
const ViewToys = ({navigation}) => {
return (
<View style={{backgroundColor: '#ffce20', height: '100%'}}>
<View>
<FLToyCard navigation={navigation}/>
</View>
</View>
)
}
export default ViewToys
change this <FLToyCard /> to this <FLToyCard navigation={navigation} />
and you are all done.
you are getting undefined in navigation in FLToyCard component that's why you are getting this error.
This error come when we do not put these mention in a page
import { NavigationContainer,useFocusEffect } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
So I think put above in every page once your problem will solve,

ReactNative; How to call new component to open new screen?

I want to open new screen from Nextpage.js ,after "onPress" worked, everything still same, NextPage not show on screen but not error. How should I do?
import NextPage from './NextPage';
function onClick() {
<NextPage/>
}
<TouchableHighlight onPress = {onClick}>
<View style={[styles.itemContainer, { backgroundColor: item.code }]}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemCode}>{item.code}</Text>
</View>
</TouchableHighlight>
you can't call a screen like that. If you want to navigate to any other screen in your case NextPage, you should define it in your navigation stack first. After that, you can call function navigation.navigate("NextPage") to navigate to next page.
Navigator file:
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import * as React from 'react';
import Home from '../screens/Home';
import Next from '../screens/Next';
const Stack = createStackNavigator();
function App({initialRouteName = 'Home'}) {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Home"
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Next" component={Next} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
Suppose you are navigating from Home to NextPage
import React from 'react';
import {StyleSheet, Text, View} from 'react-native';
export default function Home(props) {
function onClick() {
props.navigation.navigate('NextPage');
}
return (
<TouchableHighlight onPress={onClick}>
<View style={[styles.itemContainer, {backgroundColor: item.code}]}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemCode}>{item.code}</Text>
</View>
</TouchableHighlight>
);
}
const styles = StyleSheet.create({});

How to pass data through stack navigation to a specific screen on react native tabs?

I'm creating a bottom tabs in react native, which will have two screens Home and News.
But first, user will need to Sign In and the users data will be passed from the login screen to Home screen. How do i pass those data. By using
navigation.navigate('Home', {Name: Name});
I can successfuly retrieve the data in Homescreen, if I just use two screen(Login and Home in a stack). However, when I change to navigate to the tabs(which includes Home and News), it doesnt work with error 'Undefined is not an object(evaluating 'route.params.Name'.
May you guys show me which part did I miss?
Here's the app.js code.
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import HomeScreen from './homescreen';
import NewsScreen from './newsscreen';
import LoginScreen from './loginscreen';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createStackNavigator } from '#react-navigation/stack';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="News" component={NewsScreen} />
</Tab.Navigator>
);
}
const LoginStack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<LoginStack.Navigator screenOptions={{headerShown: false}}
initialRouteName="Login">
<LoginStack.Screen name="Login"component={LoginScreen}/>
<LoginStack.Screen name="MyTabs" component={MyTabs} />
</LoginStack.Navigator>
</NavigationContainer>
);
}
export default App;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Following is the homescreen code:
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default function HomeScreen({route, navigation}) {
var Name = route.params.Name;
return (
<View style={styles.container}>
<Text>{Name}</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
And finally here's the login code:
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
export default function LoginScreen({navigation}) {
const Name = 'Boy';
const login = () => {
navigation.navigate('MyTabs', {Name: 'Boy'});}
return (
<View style={styles.container}>
<Text>LoginScreen</Text>
<TouchableOpacity
onPress={login}
><Text
>LOGIN</Text>
</TouchableOpacity>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
})
I'm trying to learn how to pass data from a screen to another screen, in which the screen is located inside a tab stack. I hope you guys can understand the question and provide me with your opinion and solution. Thanks.
Output:
It needed just this little modification in MyTabs component:
function MyTabs({ navigation, route }) {
const { name } = route.params;
console.log(name);
return (
<Tab.Navigator>
<Tab.Screen
name="Home"
component={() => <HomeScreen name={route.params.name} />}
/>
<Tab.Screen name="News" component={NewsScreen} />
</Tab.Navigator>
);
}
Here is the working solution:
App.js
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
import HomeScreen from './home';
import NewsScreen from './newscreen';
import LoginScreen from './login';
// You can import from local files
const Tab = createBottomTabNavigator();
function MyTabs({ navigation, route }) {
const { name } = route.params;
console.log(name);
return (
<Tab.Navigator>
<Tab.Screen
name="Home"
component={() => <HomeScreen name={route.params.name} />}
/>
<Tab.Screen name="News" component={NewsScreen} />
</Tab.Navigator>
);
}
const LoginStack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<LoginStack.Navigator
screenOptions={{ headerShown: true }}
initialRouteName="Login">
<LoginStack.Screen name="Login" component={LoginScreen} />
<LoginStack.Screen name="MyTabs" component={MyTabs} />
</LoginStack.Navigator>
</NavigationContainer>
);
}
export default App;
LoginScreen
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import React from "react";
export default function LoginScreen({ navigation }) {
const Name = 'Name From Login Screen';
const login = () => {
console.log("hi");
navigation.navigate('MyTabs', { name : Name });
}
return (
<View style={styles.container}>
<View style={styles.bottomView}>
<TouchableOpacity onPress={login} style={styles.button}>
<Text style={styles.textStyle}>LOGIN</Text>
</TouchableOpacity>
</View>
</View>
);
}
Home.js
import { Text, View, StyleSheet } from 'react-native';
import React from "react";
export default function HomeScreen({route, navigation, name}) {
console.log("***",name)
return (
<View style={styles.container}>
<Text style={styles.name}>{name}</Text>
</View>
);
}
Working Expo Snack example.
It's a little complicated to explain react native screens once you start combining bottomtabnavigator and stack navigator and even drawernavigation.
you may need to create stack navigation inside tab navigation like this.
//creating a separate stack within your tab
const HomeStack = createStackNavigator()
const HomeStackNavigator = () => {
return (
<HomeStack.Navigator screenOptions={{headerShown: false}}
initialRouteName="HomeScreen">
<HomeStack.Screen name="Home"component={HomeScreen}/>
</HomeStack.Navigator>
)
}
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator initialRouteName="HomeStackNavigator">
<Tab.Screen name="HomeStackNavigator" component={HomeStackNavigator} />
<Tab.Screen name="News" component={NewsScreen} />
</Tab.Navigator>
);
}
I believe, different navigators doesn't really talk to each other well. If you are using different navigator be prepare to nest stack navigators inside them.
The idea is, the parent of each display component should be a stack navigator. This will also allow you to better control your screenOptions.

can't find variable navigation in other component in react-native

This is my App.js
import React from "react";
import Menu from "./components/Menu";
import HomeScreen from "./views/HomeScreen";
import SecondScreen from "./views/SecondScreen";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
const Stack = createStackNavigator();
export default function App() {
return (
<Container>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
<Stack.Screen name="Second" component={SecondSCreen} />
</Stack.Navigator>
</NavigationContainer>
<Menu></Menu>
</Container>
);
}
It works, because it shows the HomeScreen on default, but I want to navigate to the second screen via the Menu-component:
import React from "react";
import { View, Text, TouchableOpacity } from "react-native";
class Menu extends React.Component {
render() {
return (
<View>
<TouchableOpacity
onPress={() => {
alert("Hi");
}}
>
<Text>HomeScreen</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
navigation.navigate("Second");
}}
>
<Text>Screen 2</Text>
</TouchableOpacity>
</View>
);
}
}
export default Menu;
The component is visible, but when I click on the second button I expect the SecondScreen to be openend.
But I get this error:
Can't find variable: navigation
What am I missing?
You should use the navigationRef for this scenario, as your menu is outside the navigation container
import { NavigationContainer } from '#react-navigation/native';
import { navigationRef } from './RootNavigation';
export default function App() {
return (
<Container>
<NavigationContainer ref={navigationRef}>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
<Stack.Screen name="Second" component={SecondSCreen} />
</Stack.Navigator>
</NavigationContainer>
<Menu></Menu>
</Container>
);
}
// RootNavigation.js
import * as React from 'react';
export const navigationRef = React.createRef();
export function navigate(name, params) {
navigationRef.current?.navigate(name, params);
}
In menu js,
import {navigate} from 'RootNavigation';
class Menu extends React.Component {
render() {
return (
<View>
<TouchableOpacity
onPress={() => {
alert("Hi");
}}
>
<Text>HomeScreen</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
navigate("Second");
}}
>
<Text>Screen 2</Text>
</TouchableOpacity>
</View>
);
}
}