undefined is not an object (evaluating 'this.props.navigation') - React Native - javascript

undefined is not an object (evaluating 'this.props.navigation')
I keep on getting this error, and I can't figure out what's wrong with my code. The program is meant to check if the user is logged in, and if they aren't, they are directed to the Sign Up page. However, it doesn't seem to work. Could anybody tell me what is wrong?
Loading Screen:
import React, {Component} from 'react';
import { View, Text, ActivityIndicator, StyleSheet } from 'react-native'
import firebase from 'firebase'
export default class Loading extends React.Component{
componentDidMount() {
firebase.auth().onAuthStateChanged(function(user) {
console.log(user)
if (user) {
console.log('user is signed in')
} else {
console.log('user is not signed in')
this.props.navigation.navigate('SignUp')
}
});
}
render() {
return (
<View style={styles.container}>
<Text>Loading</Text>
<ActivityIndicator size="large" />
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
})
App.js:
import {createAppContainer, createSwitchNavigator, SwitchNavigator} from 'react-navigation';
import {createBottomTabNavigator} from 'react-navigation-tabs';
import Ion from 'react-native-vector-icons/Ionicons';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import Home from './src/screens/Home';
import Following from './src/screens/Following';
import Add from './src/screens/Add';
import Groups from './src/screens/Groups';
import Profile from './src/screens/Profile';
import Loading from './src/screens/Loading';
import SignUp from './src/screens/SignUp';
import Login from './src/screens/Login';
import React, {Component} from 'react';
const MainTabs = createBottomTabNavigator(
{
Home: {
screen: Home,
navigationOptions: {
tabBarLabel: "HOME",
tabBarIcon: ({ tintColor }) => (
<FontAwesome name="home" color={tintColor} size={24} />
)
}
},
Following: {
screen: Following,
navigationOptions: {
tabBarLabel: "FOLLOWING",
tabBarIcon: ({ tintColor }) => (
<FontAwesome5 name="user-friends" color={tintColor} size={24} />
)
}
},
Add: {
screen: Add,
navigationOptions: {
tabBarLabel: () => null,
tabBarIcon: () => (
<Ion name="ios-add-circle" color="white" size={50} />
)
}
},
Groups: {
screen: Groups,
navigationOptions: {
tabBarLabel: "GROUPS",
tabBarIcon: ({ tintColor }) => (
<MaterialIcons name="group-work" color={tintColor} size={30} />
)
}
},
Profile: {
screen: Profile,
navigationOptions: {
tabBarLabel: "PROFILE",
tabBarIcon: ({ tintColor }) => (
<FontAwesome5 name="user-circle" color={tintColor} size={24} />
)
}
},
},
{
tabBarOptions: {
activeTintColor: "white",
inactiveTintColor: "#CFC8EF",
style: {
backgroundColor: "#2C2061",
borderTopWidth: 0,
shadowOffset: { width: 5, height: 3 },
shadowColor: "black",
shadowOpacity: 0.5,
elevation: 5
}
}
},
);
const switchNavigator = createSwitchNavigator(
{ Loading, SignUp, Login, MainTabs},
{ initialRouteName: "Loading" }
);
const App = createAppContainer(switchNavigator);
export default App;

try ES6 method, which binds this automatically,
componentDidMount = () => { // changes are here
firebase.auth().onAuthStateChanged((user)=> { // changes are here
console.log(user)
if (user) {
console.log('user is signed in')
} else {
console.log('user is not signed in')
this.props.navigation.navigate('SignUp')
}
});
}
if the error still persists which logically should not, but if then try this,
import {withNavigation} from 'react-navigation';
...
class Loading extends React.Component{
...
...
...
}
export default withNavigation(Loading)

Related

Passing data between Stack navigators in one Drawer navigator

Is possible to pass data between two stack navigators, in one drawer navigator?
i.e:
-DrawerNavigationA
--StackNavigationA
--StackNavigationB
I want to pass some data (you can see in code below) from StackNavigationB to StackNavigationA. What I need to do? I am looking a 3rd day for some solution, but I found nothing.
App.js
import React from 'react';
import Navigator from './routes/drawer';
export default function App() {
return (
<Navigator />
);
}
Home.js
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
export default function Home({ navigation }) {
return (
<View style={styles.container}>
<Text> Hello {/* here i want to show a passed value from ChooseName */} from home! </Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
ChooseName.js
import React, { useState } from 'react';
import { StyleSheet, View, Text, TouchableOpacity, FlatList } from 'react-native';
export default function ChooseName({ navigation }) {
const [names, setNames] = useState([
{ name: 'Adam', key: '1' },
{ name: 'Ivan', key: '2' },
{ name: 'Josh', key: '3' },
]);
//after clicking on the name
const onPressHandler = (name) => {
// //Do something to pass name to Home screen
// //and navigate to Home screen
navigation.navigate('HomeStack');
console.log('hello' + name);
}
return (
<View style={styles.container}>
<FlatList data={names} renderItem={({ item }) => (
<TouchableOpacity onPress={() => onPressHandler(item.name)}>
<Text style={styles.name}>{ item.name }</Text>
</TouchableOpacity>
)} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
name: {
padding: 10,
marginBottom: 10,
}
});
HomeStack.js
import { createStackNavigator } from 'react-navigation-stack';
import Home from '../screens/Home';
const screens = {
Home: {
screen: Home,
navigationOptions: {
title: 'Home',
},
},
};
const HomeStack = createStackNavigator(screens, {
defaultNavigationOptions: {
headerTintColor: '#444',
headerStyle: { backgroundColor: '#eee', height: 60 }
}
});
export default HomeStack;
ChooseNameStack.js
import { createStackNavigator } from 'react-navigation-stack';
import ChooseName from '../screens/ChooseName';
const screens = {
ChooseName: {
screen: ChooseName,
navigationOptions: {
title: 'ChooseName'
},
},
}
const AboutStack = createStackNavigator(screens, {
defaultNavigationOptions: {
headerTintColor: '#444',
headerStyle: { backgroundColor: '#eee', height: 60 },
}
});
export default AboutStack;
router.js
import { createDrawerNavigator } from 'react-navigation-drawer';
import { createAppContainer } from 'react-navigation';
// stacks
import HomeStack from './HomeStack';
import ChooseNameStack from './ChooseNameStack';
// drawer navigation options
const RootDrawerNavigator = createDrawerNavigator({
HomeStack: {
screen: HomeStack,
},
ChooseNameStack: {
screen: ChooseNameStack,
},
});
export default createAppContainer(RootDrawerNavigator);
navigation versions
"react-navigation": "^4.3.9",
"react-navigation-drawer": "^2.4.13",
"react-navigation-stack": "^2.4.0"
As you can see, I want to pass a name from ChooseName to Home, when Touchable is clicked and then navigate to Home page.
Thank you for responses.
you can pass it as props like: navigation.navigate("Home",{'id':2222}) and you are able to get it in the next route. Hope it helps
you will change this line in ChooseName.js navigation.navigate('HomeStack'); in your code to navigation.navigate('HomeStack',{name:name});
then in your Home.js change this export default function Home({ navigation }) to export default function Home({ navigation, route }) and add a console.log(route) and console.log(navigation) to understand the situation that is all

TabNavigator CustomTabComponent onPress not navigating to AddCar page

I am using A TabNavigator inside Stack navigator. Stack Navigator Contains 2 Pages Tab Navigator page and AddCar Page, inside TabNavigator I am using Custom Tab Bar Component which uses a custom Button Component when I press on that button it's not routing to Add Car Page,
I have tried to launch the page which is in the tabNavigator also but not working
here is the stack navigator code:
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { createAppContainer, createStackNavigator } from 'react-navigation';
//Screens
import MainTabs from '../navigators/mainTabNavigator';
import AddCar from '../add_car/container/addCar';
class Navigator extends Component {
render() {
return (
<AppNavigator />
);
}
}
const navigator = createStackNavigator({
MainTabs: { screen: MainTabs },
AddCar: { screen: AddCar }
}, {
initialRouteName: 'MainTabs',
headerMode: 'none'
});
const AppNavigator = createAppContainer(navigator);
export default Navigator;
here is the tabNavigator:
/* eslint-disable no-undef */
/* eslint-disable max-len */
/* eslint-disable no-unused-expressions */
/* eslint-disable react/require-extension */
import React, { Component } from 'react';
import { StyleSheet } from 'react-native';
import { createAppContainer, createBottomTabNavigator, withNavigation, NavigationActions, getActiveChildNavigationOptions } from 'react-navigation';
import Icons from 'react-native-vector-icons/Ionicons';
import { OpacityButton } from '../utilities/buttons';
import Colors from '../Metrics/colors';
//Screens
import CarsList from '../cars_list/container/carsList';
import AddCar from '../add_car/container/addCar';
import Screen from '../screen';
class MainTabNavigator extends Component {
render() {
return (
<AppContainer />
);
}
}
const size = 25;
const routeConfigs = {
CarsList: {
screen: CarsList,
navigationOptions: () => ({
tabBarIcon: ({ tintColor }) => (
<Icons
name="ios-information-circle"
color={tintColor}
size={size}
/>
),
}),
},
AppovedList: {
screen: Screen,
navigationOptions: () => ({
tabBarIcon: ({ tintColor }) => (
<Icons
name="ios-options"
color={tintColor}
size={size}
/>
),
}),
},
AddCars: {
screen: AddCar,
navigationOptions: () => ({
tabBarButtonComponent: () => (
<OpacityButton
name="ios-add-circle-outline"
onPress={() => NavigationActions.navigate('addCar')}
size={size}
color={Colors.brandColor}
containerStyle={{ borderWidth: StyleSheet.hairlineWidth, borderColor: Colors.light, backgroundColor: Colors.white }}
/>
)
})
},
NavList: {
screen: CarsList,
navigationOptions: () => ({
tabBarIcon: ({ tintColor }) => (
<Icons
name="ios-albums"
color={tintColor}
size={size}
/>
),
}),
},
Profile: {
screen: CarsList,
navigationOptions: () => ({
tabBarIcon: ({ tintColor }) => (
<Icons
name="ios-contact"
color={tintColor}
size={size}
/>
),
}),
},
};
const navigationOptions = {
tabBarOptions: {
activeTintColor: Colors.brandColor,
inactiveTintColor: Colors.lightBlack,
showLabel: false,
animation: true
},
headerMode: 'none'
};
const navigator = createBottomTabNavigator(routeConfigs, navigationOptions);
const AppContainer = createAppContainer(navigator);
export default MainTabNavigator;
I Want To navigate to AddCarPage which is there in the stacknavigator, On press of that Custom Tab Component Button ,
Like instagram plus icon opens new page.
for the custom component, you can just call it under tabBarIcon
AddCars: {
screen: AddCar,
navigationOptions: () => ({
tabBarIcon:
<OpacityButton
name="ios-add-circle-outline"
size={size}
color={Colors.brandColor}
containerStyle={{ borderWidth: StyleSheet.hairlineWidth, borderColor: Colors.light, backgroundColor: Colors.white }}
/>
})
},

Hide previous tabs and header react-navigation v3

I have a createMaterialTopTabNavigator and when I press to navigate on another screen, I would like hide the tabs and the header but display the current header ("Pronostics détails"). It's possible ?
The code of MontanteTab :
import React from 'react';
import {ScrollView, View, FlatList} from 'react-native';
import {ListItem} from "react-native-elements";
import pronostics from "../../data/Constants/Pronostics";
import {createAppContainer, createStackNavigator} from "react-navigation";
import PronosticsDetailsScreen from "../../screens/PronosticsDetailsScreen";
class MontanteTab extends React.Component {
render() {
return (
<View>
<ScrollView>
<View>
<FlatList
data={pronostics}
keyExtractor={(item, index) => index.toString()}
renderItem={({item}) => (
<ListItem
key={item.id}
leftAvatar={{source: {uri: item.image}}}
title={item.competition}
subtitle={item.equipe_domicile + ' - ' + item.equipe_exterieur}
onPress={() => this.props.navigation.navigate('PronosticsDetails', {name: 'Jnae'})}
/>
)}
/>
</View>
</ScrollView>
</View>
);
}
}
const MontanteStack = createStackNavigator(
{
Montante: {
screen: MontanteTab,
navigationOptions: ({navigation}) => ({
header: null,
}),
},
PronosticsDetails: {
screen: PronosticsDetailsScreen,
navigationOptions: ({navigation}) => ({
headerMode: 'screen',
headerTitle: 'Pronostics détails',
headerStyle: {
backgroundColor: '#000000',
textAlign: 'center',
},
headerTintColor: '#ffffff',
headerTitleStyle: {
color: '#c7943e',
textAlign: 'center',
alignSelf: 'center',
justifyContent: 'center',
flex: 1,
}
}),
},
},
{
initialRouteName: 'Montante',
}
);
export default createAppContainer(MontanteStack);
The code of PronosticsDetailsScreen :
import React from 'react';
import {
StyleSheet,
View,
} from 'react-native';
import {Text} from "react-native-elements";
export default class PronosticsDetailsScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Détails</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
contentContainer: {
paddingTop: 30,
},
image: {
height: 100,
width: 100,
}
});
I tried to set the header to "null" but the current header is also hidden..
Thank you in advance for your help
Life would be easy if the API supported the ability to hide createMaterialTopTabNavigator()! But this option exists for bottom tabs, not top.
After doing research and test, I think it is possible to hide the tabs and header. It's a matter of playing with the nested navigation. (Inspired by: https://github.com/react-navigation/react-navigation/issues/1979 and Hide parent's navigation header from the nested navigator)
For example:
Pushing the back button on Screen 07 will go back to Screen 06.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { createStackNavigator, createAppContainer, createBottomTabNavigator, createMaterialTopTabNavigator } from 'react-navigation';
import Screen01 from './screens/Screen01';
import Screen02 from './screens/Screen02';
import Screen03 from './screens/Screen03';
import Screen04 from './screens/Screen04';
import Screen05 from './screens/Screen05';
import Screen06 from './screens/Screen06';
import Screen07 from './screens/Screen07';
const AppStackNavigator = createStackNavigator({
home: {
screen: Screen01
},
flowOne: {
screen: createStackNavigator({
page02: {
screen: Screen02 },
page03: {
screen: Screen03 },
flowTwo: {
screen: createBottomTabNavigator({
page04: {
screen: Screen04
},
flowThree: {
screen: createMaterialTopTabNavigator({
page05: {
screen: Screen05
},
page06: {
screen: Screen06
},
})
}
}) // end createBottomTabNavigator, end flowThree
},
flowFour: createStackNavigator({
page07: {screen: Screen07}
}
) // end flowFour
},
{
navigationOptions: {header: null} // hides header in flowOne
})
},
});
const AppContainer = createAppContainer(AppStackNavigator);
export default class App extends React.Component {
render() {
return (
<AppContainer />
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
I've got Expo demo here: https://exp.host/#project8888/NavigationDemo

React native - React Navigation for multiple routes

I am wondering is there any way to make StackNavigator inside TabNavigator with react-navigation, Right now I have TabNavigator like that in Router.js. I want app inside Add.js (Add screen) to make StackNavigator inside ListItem. Every element of ListItem Should get user to other screen. So If I press first option it should get me to "AddCalendarEvent" etc. Like you see in Add.js file on addList constant
Router.js
import React from 'react';
import {
AppRegistry,
Text,
View,
Button
} from 'react-native';
import {StackNavigator, TabNavigator} from 'react-navigation';
import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome';
import EntypoIcon from 'react-native-vector-icons/Entypo';
import Login from './Login';
import Menu from './Menu';
import Desktop from './Desktop';
import Notifications from './Notifications';
import Today from './Today';
import Add from './Add';
const onClickNavigation = StackNavigator({
Login: {screen: Login}
});
const estimobileapplication = TabNavigator({
Add: {
screen: Add, navigationOptions: {
title: 'Dodaj',
label: 'Dodaj',
tabBarIcon: ({tintColor}) => (<FontAwesomeIcon name="plus-circle" size={24} color="#666"/>)
}
},
Desktop: {
screen: Desktop, navigationOptions: {
title: 'Pulpit',
label: 'Pulpit',
tabBarIcon: ({tintColor}) => (<FontAwesomeIcon name="th-large" size={24} color="#666"/>)
}
},
Notifications: {
screen: Notifications, navigationOptions: {
title: 'Powiadomienia',
label: 'Powiadomienia',
tabBarIcon: ({tintColor}) => (<FontAwesomeIcon name="envelope" size={24} color="#666"/>)
}
},
Today: {
screen: Today, navigationOptions: {
title: 'Na dziś',
label: 'Na dziś',
tabBarIcon: ({tintColor}) => (<FontAwesomeIcon name="check-square" size={24} color="#666"/>)
}
},
Menu: {
screen: Menu, navigationOptions: {
title: 'Menu',
label: 'Menu',
tabBarIcon: ({tintColor}) => (<EntypoIcon name="menu" size={24} color="#666"/>),
}
}
}, {
tabBarOptions: {
activeTintColor: '#26b7ff',
inactiveTintColor: '#ffffff',
activeBackgroundColor: '#2E3035',
style: {
backgroundColor: '#14191f',
}
}
});
AppRegistry.registerComponent('estimobileapplication', () => estimobileapplication);
Add.js
import React, {Component} from 'react';
import {
ScrollView,
Text,
View,
NavigatorIOS
} from 'react-native';
import {List, ListItem} from 'react-native-elements';
import AddCalendarEvent from './add_offer_components/AddCalendarEvent';
import AddOfferFull from './add_offer_components/AddOfferFull';
import AddOfferQuick from './add_offer_components/AddOfferQuick';
import AddQuestion from './add_offer_components/AddQuestion';
import AddUser from './add_offer_components/AddUser';
import GetInvoice from './add_offer_components/GetInvoice';
import SellBuyTransaction from './add_offer_components/SellBuyTransaction';
import SendEmailToClient from './add_offer_components/SendEmailToClient';
import SendNotification from './add_offer_components/SendNotification';
import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome';
class Add extends Component {
onShowMore() {
this.props.navigation.navigate('AddCalendarEvent');
};
render() {
const addList = [
{
title: 'Nowa oferta lub zlecenie - szybkie dodanie',
component: AddOfferQuick
},
{
title: 'Nowa oferta lub zlecenie - pełne dodanie',
component: AddOfferFull
},
{
title: 'Nowe zapytanie',
component: AddQuestion
},
{
title: 'Nowy termin w kalendarzu',
component: AddCalendarEvent
},
{
title: 'Wyślij e-mail do klienta',
component: SendEmailToClient
},
{
title: 'Transakcja kupna/najmu',
component: SellBuyTransaction
},
{
title: 'Wystaw fakturę',
component: GetInvoice
},
{
title: 'Wyślij powiadomienie',
component: SendNotification
},
{
title: 'Dodaj użytkownika',
component: AddUser
}
];
return (
<ScrollView style={{marginTop: 50, paddingLeft: 20}}>
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
<FontAwesomeIcon name="plus-circle" size={30} color="#26b7ff"/>
<Text style={{textAlign: 'left', fontSize: 30, color: '#444444', marginLeft: 10}}>
Dodaj
</Text>
</View>
<List>
{addList.map((item, i) => (
<ListItem
key={i}
title={item.title}
onPress={() => this.onShowMore()}
/>
))}
</List>
</ScrollView>
);
}
}
export default Add;
According tho the react navigation docs you can nest as many navigators as you need. Just instead of defining a component for your tab in "screen", define a StackNavigator. This way, it will display the first component that your StakNavigator Shows.
Then in each item you define a navigate() to the next screen you need (I assume is the same screen for every item in the list) and pass the required data as a prop.

undefined is not an object (evaluating 'this.props.navigation.navigate') - React Native

I am trying to make my first React Native Android app and I am getting this error:
undefined is not an object (evaluating 'this.props.navigation.navigate')
This is the code:
import React from 'react';
import { StyleSheet, Text, View, Button, TextInput } from 'react-native';
import { StackNavigator } from 'react-navigation';
export default class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
};
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Button
title="Show Centers near me"
onPress={() =>
navigate('Results', "Search Term")
}
/>
<Text>or</Text>
</View>
);
}
}
class ResultsScreen extends React.Component {
static navigationOptions = {
title: 'Results',
};
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>Hi</Text>
</View>
);
}
}
const App = StackNavigator({
Home: { screen: HomeScreen },
Results: { screen: ResultsScreen }
});
I can not figure out why the error is coming.
You are exporting the component wrong. You should get rid of the export default on your class HomeScreen definition and at the bottom of the file do export default App;
If you are handling it in AppContainer and not able to access while opening drawer menu. You can try below snippets.
const HomeStackNavigator = createStackNavigator({ Home: {
screen: Home,
navigationOptions : ({navigation}) => ({
title: 'Home',
headerStyle: {
backgroundColor: "#512DA8"
},
headerTitleStyle: {
color: "#fff"
},
headerTintColor: "#fff",
headerLeft: <TouchableOpacity onPress={ () => navigation.openDrawer()}>
<Image
source={require('./images/menu_burger.png')}
style={{width: 24, height: 24, padding: 5, marginLeft: 5}}/>
</TouchableOpacity>
}) } }, { initialRouteName: 'DumontHome' })
Try without 'search term' or in this way:
navigate('route', {item:'search term'})

Categories

Resources