undefined is not an object (evaluation this.props.navigation.navigate) - javascript

I have a router.js like this:
import React from 'react';
import { TabNavigator, StackNavigator } from 'react-navigation';
import Login from '../components/login/Login';
import Activation from '../components/login/Activation';
import Phone from '../components/login/Phone';
import ContainerNavs from '../components/navs/ContainerNavs';
import Notification from '../components/navs/notification/Notification';
import Question from '../components/navs/notification/Question';
export const LoginStack = StackNavigator({
Login: {
screen: Login,
},
Phone: {
screen: Phone,
},
Activation: {
screen: Activation,
}
},
{
headerMode: 'none'
});
export const HomeStack = StackNavigator({
Home: {
screen: ContainerNavs,
},
Notifications: {
screen: Notification,
},
Question: {
screen: Question,
},
},
{
headerMode: 'none'
});
export const Root = StackNavigator({
Login: {
screen: LoginStack,
},
Home:{
screen: HomeStack,
},
},{
mode: 'modal',
headerMode: 'none',
initialRouteName: 'Login',
}
);
ContainerNavs is a FooterTab from native-base library.
my Notification component rendered inside ContainerNavs:
renderSelectedTab () {
switch (this.state.selectedTab) {
case 'home':
return (<Home />);
break;
case 'search':
return (<Text>search</Text>);
break;
case 'new':
return (<New />);
break;
case 'notification':
return (<Notification />);
break;
case 'profile':
return (<Profile />);
break;
}
}
inside Notification component I wrote this codes:
goTo(page){
this.props.navigation.navigate(page);
}
render() {
return (
<List>
<ListItem>
<Card style={{backgroundColor:'#f2f2f6'}}>
<Button
onPress={()=>this.goTo('Question')}
>
<Text>Toast</Text>
</Button>
but when I click on Toast button I got this error:
undefined is not an object (evaluation this.props.navigation.navigate)
I think I should pass navigation from ContainerNavs to Notification.

Solved by this trick:
return (<Notification navigation={this.props.navigation} />);

Related

React Native not passing data through navigation param

I'm trying to pass some data when navigating to another screen, but it's not working. It navigates to the screen but the data is undefined.
I have this button on the 'Produto' Screen:
onPress={() => {
props.navigation.navigate("Login", {
test: "This is just a test"
});
}}
Login Screen:
const LoginScreen = props => {
const test = props.navigation.getParam("test");
console.log(test);
test is undefined.
My Navigator (I removed imports and other stuff from this snippet):
const MainNavigator = createStackNavigator(
{
Home: HomeScreen,
Produto: ProdutoScreen,
},
{
initialRouteName: "Home"
}
);
const LoginNavigator = createStackNavigator(
{
Login: LoginScreen
}
);
const DrawerNavigator = createDrawerNavigator(
{
Main: {
screen: MainNavigator
},
Login: {
screen: LoginNavigator
}
}
);
const SwitchNavigator = createSwitchNavigator({
Start: StartScreen,
Home: DrawerNavigator
});
Just update the line where you are trying to access the param. Like this,
const LoginScreen = props => {
const test = props.navigation.state.params.test;
console.log(test);
}
Just do this
const MainNavigator = createStackNavigator(
{
Home: HomeScreen,
Produto: ProdutoScreen,
Login: LoginScreen, //this will resolve your issue
},
{
initialRouteName: "Home"
}
);

The navigation drawer does not refresh until I restart the appliction

I have a problem with React Native Navigation Library, The problem is that I implemented logout in my application that forget the AsyncStorage presistent data, the problem starts when I log to another account without restarting the application, I find that the navigation drawer does not sense the change in AsyncStorage although I update the state depending on returned value from AsyncStorage as if it is cached, so I want a method to refresh the navigation draw or flush the navigation drawer cached view once I made a logout out and re-logged to another account to change the name and thumbnail content.
I tried to find any event listener or any callback where I can replace with my own logic but I didn't find anything closely related.
I also tried to replace AsyncStorage with axios call directly to fetch the user but nothing worked.
My Navigator Code:
import {createStackNavigator, createAppContainer, createDrawerNavigator} from 'react-navigation';
import {
Login,
Register,
ShowProperty,
AllProps,
Splash,
Search,
SearchResult,
EditProfile,
AddProperty,
Home,
HomeSearch,
Contact,
About,
} from "./pages";
import {NavDrawer} from "./components";
import {Dimensions} from 'react-native';
const StackNavigator = createStackNavigator(
{
Welcome: {
screen: Splash
},
Register: {
screen: Register
},
Login: {
screen: Login
},
ShowProps: {
screen: AllProps
},
ShowProp: {
screen: ShowProperty
},
Search: {
screen: Search
},
SearchResult: {
screen: SearchResult
},
EditProfile: {
screen: EditProfile
},
AddProperty: {
screen: AddProperty
},
Home: {
screen: Home,
},
HomeSearch: {
screen: HomeSearch,
},
About: {
screen: About,
},
Contact: {
screen: Contact,
},
},
{
initialRouteName: "Welcome",
headerMode: "none",
duration: 500,
lazy: true,
}
);
const DrawerNavigation = createDrawerNavigator({
Drawer: {
screen: NavDrawer,
},
Application: StackNavigator,
}, {
initialRouteName: "Application",
headerMode: "none",
duration: 500,
lazy: true,
contentComponent: NavDrawer,
drawerWidth: Dimensions.get('window').width,
drawerPosition: 'right',
});
export default createAppContainer(DrawerNavigation);
and this is my custom drawer code:
import React, {Component} from 'react';
import {ActivityIndicator, Image, ImageBackground, StyleSheet, View, TouchableOpacity} from 'react-native';
import Responsive from "./Responsive";
import AsyncStorage from '#react-native-community/async-storage';
import {FontText} from "./index";
import Icon from 'react-native-vector-icons/EvilIcons';
import axios from 'axios';
import {NavigationActions, StackActions} from "react-navigation";
class NavDrawer extends Component {
state = {
profile_picture: null,
name: null,
};
componentDidMount = async () => {
const user = await AsyncStorage.getItem('#UserData:user');
if(user !== null){
let {first_name, last_name, profile_picture} = JSON.parse(user).data;
console.log(first_name, last_name, profile_picture);
let stateObj = {
profile_picture: profile_picture ? profile_picture : null,
name: first_name && last_name ? first_name +" "+ last_name : null,
};
this.setState({
...stateObj
});
}
};
handleNavigation = (routeName) => (e) => {
this.props.navigation.closeDrawer();
this.props.navigation.navigate(routeName);
};
resetAndNavigate = (route) => {
let navigator = StackActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
routeName: route,
}),
],
});
this.props.navigation.dispatch(navigator);
};
clearCredentials = async (e) => {
try{
await AsyncStorage.clear();
this.resetAndNavigate("Login");
}
catch (e) {
this.resetAndNavigate("Login");
}
};
render() {
return (
<ImageBackground source={require('../images/drawer-image.jpg')} style={style.backgroundStyle}>
<View style={style.infoWrapper}>
<Image source={this.state.profile_picture ?
{uri: this.state.profile_picture} :
require('../images/man.jpg')
} style={style.img}
/>
<FontText wFont={'bold'} style={style.nameStyle}>
{this.state.name ? this.state.name : "Loading.."}
</FontText>
</View>
<View style={style.navigators}>
<TouchableOpacity onPress={this.handleNavigation('Home')}>
<FontText style={style.nameStyle}>
Home
</FontText>
</TouchableOpacity>
<TouchableOpacity onPress={this.handleNavigation('About')}>
<FontText style={style.nameStyle}>
About us
</FontText>
</TouchableOpacity>
<TouchableOpacity onPress={this.handleNavigation('Contact')}>
<FontText style={style.nameStyle}>
Contact us
</FontText>
</TouchableOpacity>
<TouchableOpacity onPress={this.clearCredentials}>
<FontText style={style.nameStyle}>
Logout
</FontText>
</TouchableOpacity>
<TouchableOpacity style={style.dismiss} onPress={this.props.navigation.closeDrawer}>
<Icon name={"close"} color={"#fff"} size={35}/>
</TouchableOpacity>
</View>
</ImageBackground>
);
}
}
export default NavDrawer;
The expected is when I logged out and re-login with another account is to see the name and photo of current user in drawer.
The actual behavior is that navigation drawer caches the custom component for the drawer and when I log with another user I see the information of the previous user.

I want to put a materialTopTabNavigator under the header echo with navigationOptions of a stack

I want to put the buttons under the header that I have made with the stack, but I can not think of how I leave a part of the code of how I have done it.
//stacks
import React from "react";
import { connect } from "react-redux";
import { createStackNavigator } from "react-navigation";
import ScreenAutoridades from "../../views/autoridades/ScreenAutoridades";
import DetallesAutoridades from "../../views/autoridades/autoridades/Components/DetallesAutoridades";
import AutoridadesList from "../../views/autoridades/autoridades/Components/AutoridadesList";
import ButtonMenu from "../components/ButtonMenu";
import ButtonHome from "../components/ButtonHome";
import { defaultNavigationOptions } from "../components/stylesNavigations";
let AutoridadesRedux = connect(state => ({
autoridades: state.autoridades
}))(ScreenAutoridades);
const AutoridadesStack = createStackNavigator(
{
AUTORIDADES: {
screen: AutoridadesRedux,
navigationOptions: ({ navigation }) => {
return {
headerLeft: <ButtonMenu navigation={navigation} />,
headerRight: <ButtonHome navigation={navigation} />
};
}
},
AutoridadesList: {
screen: AutoridadesList
},
DetalleAutoridades: {
screen: DetallesAutoridades
}
},
{
defaultNavigationOptions
}
);
export { AutoridadesStack };
//Drawer
const DrawerNavigator = createDrawerNavigator(
{
Diputados: { screen: DiputadosStack },
Bloques: { screen: BloquesStack },
Interbloques: { screen: InterBloquesStack },
Comisiones: { screen: ComisionesStack },
Autoridades: { screen: AutoridadesStack },
"Sesion En Vivo": { screen: SesionEnVivoStack },
"Diputados TV": { screen: DiputadosTVStack },
"Reglamentos HCDN": { screen: PDFReglamentosStack }
},
{
contentComponent: CustomDrawerContentComponent,
drawerWidth: width / 2,
contentOptions: {
activeTintColor: white,
activeBackgroundColor: Gris_Drawer,
inactiveTintColor: "rgb(105,105,104)",
itemsContainerStyle: {
textAlign: "center"
},
labelStyle: {
fontFamily: "RobotoCondensed-Regular",
fontWeight: "100",
fontSize: 17,
marginTop: 8,
marginLeft: 10
}
},
iconContainerStyle: {
opacity: 1
}
}
);
I just want to add the createMaterialTopTabNavigator below the header made with the createStackNavigator.
What I did was put a createMaterialTopTabNavigator but at the time of adding the stacks inside I stayed up the createMaterialTopTabNavigator and below I had the navigation of the stack
You can use a navigator for a screen in creating any navigator.
For example:
import {
createMaterialTopTabNavigator,
createStackNavigator
} from 'react-navigation'
import MyComponent from '../some-component-folder/'
import MyHomeComponent from '../some-component-folder/'
import MyNavigator from '../some-navigator-folder/'
const TabNavigator = createMaterialTopTabNavigator(
{
Tab1: { screen: MyComponent }
Tab2: { screen: MyNavigator }
}
)
const StackNavigator = createStackNavigator(
{
Screen1: { screen: MyHomeComponent }
Screen2: { screen: TabNavigator }
}
)

Can't navigate to a nested DrawerNavigator route in react-navigation

I am trying out react navigation, but I seem to be having trouble with navigating to a nested DrawerNavigator route within my react native app.
After a successful login action, I would like to navigate to the Home screen but it doesn’t work
My setup looks like the following;
App.js
import React, { Component } from 'react';
import { View } from 'react-native';
import { StackNavigator, DrawerNavigator, addNavigationHelpers } from 'react-navigation';
import { Provider, connect } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import ReduxThunk from 'redux-thunk';
import reducers from './reducers';
import AppNavigator from './AppNavigator';
class App extends React.Component {
render() {
return (
<AppNavigator navigation={addNavigationHelpers({
dispatch: this.props.dispatch,
state: this.props.nav,
})} />
);
}
}
const mapStateToProps = (state) => ({
nav: state.nav
});
const AppWithNavigationState = connect(mapStateToProps)(App);
class Root extends Component {
render() {
const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
return (
<Provider store={ store }>
<View style={{ flex: 1 }}>
<AppWithNavigationState />
</View>
</Provider>
);
}
}
export default Root;
NavReducer.js
import { NavigationActions } from 'react-navigation';
import AppNavigator from '../AppNavigator';
const initialState = AppNavigator.router.getStateForAction(
NavigationActions.init()
// AppNavigator.router.getActionForPathAndParams('Main')
);
export default navReducer = (state = initialState, action) => {
const nextState = AppNavigator.router.getStateForAction(action, state);
// Simply return the original `state` if `nextState` is null or undefined.
return nextState || state;
};
AppNavigator.js
import { StackNavigator, DrawerNavigator } from 'react-navigation';
import LandingPage from './components/LandingPage';
import LoginScreen from "./components/LoginForm";
import RegistrationScreen from "./components/RegistrationForm";
import Homepage from "./components/Homepage";
const LoginStack = StackNavigator({
LandingPage: { screen: LandingPage },
Login: { screen: LoginScreen },
Registration: { screen: RegistrationScreen },
}, {
headerMode: 'none',
initialRouteName: 'LandingPage'
});
const DrawerNavigatorStack = DrawerNavigator({
Home: { screen: Homepage }
}, {
headerMode: 'none',
initialRouteName: 'Home'
});
const DrawerNavigation = StackNavigator({
DrawerStack: { screen: DrawerNavigatorStack }
}, {
headerMode: 'none',
initialRouteName: 'DrawerStack'
});
const AppNavigator = StackNavigator({
LoginStack: { screen: LoginStack },
Main: { screen: DrawerNavigation }
}, {
headerMode: 'none',
initialRouteName: 'LoginStack'
});
export default AppNavigator;
Login action
export const loginUser = ({ email, password }) => {
return (dispatch) => {
dispatch({ type: LOGIN_USER });
const data = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
password: password
})
};
const url = Globals.API_URL + 'accounts/login';
return fetch(url, data)
.then(response => {
const responseBody = JSON.parse(response._bodyText);
if (response.status === 200) {
dispatch({ type: LOGIN_USER_SUCCESS });
dispatch(NavigationActions.navigate({
routeName: ‘Home’, <=== supposed to navigate to the Home screen at this point
params: responseBody.data.access_token
}));
} else {
loginUserFail(dispatch, responseBody.message);
}
});
}
}
It successfully dispatches the LOGIN_USER_SUCCESS and the subsequent Navigation actions, but it doesn’t actually navigate to the Home screen
If I replace the ‘Home’ route with a route from the ‘LoginStack’ it will navigate to that screen with no problem. So for example, this would work
dispatch(NavigationActions.navigate({
routeName: ‘LandingPage’, <=== will successfully navigate back to the LandingPage
params: responseBody.data.access_token
}));
I’m obviously missing something, any ideas what that might be?
Thanks in advance

React Native navigate from Tabnavigator to stack navigator

I have a tab navigator where MyHomeScreen is the initial view.
In my Homescreen i have another component with an action to navigate to another screen but when i press it is not navigating to AnotherscreenWithouttab.
MyHomeScreen
render() {
const navigation = this.props.navigation;
const {navigate} = this.props.navigation;
return (
<Actionscreen
navigation={navigation}
/>
</View>
);
}
ActionScreen
render() {
const {navigate} = this.props.navigation;
return (
<View >
<TouchableOpacity
onPress={ () => navigate('AnotherscreenWithouttabRoute', { param1: 'Route-1' }) }
><Text>go to another screen</Text></TouchableOpacity>
</View>
);
}
TabNavigator
const DashboardTab = TabNavigator(
{
Home: {
screen: MyHomeScreen,
path: '',
},
People: {
screen: FeedScreen,
path: 'cart',
}
}
class DashboardTabComponent extends Component {
constructor(props) {
super(props);
}
render() {
const {
navigation,
screenProps
} = this.props;
return(
<DashboardTab
//navigation={navigation}
screenProps={screenProps}
//screenProps={this.state}
/>
);
}
}
router.js
import React, { Component } from 'react';
import { Text, View, ScrollView, TouchableOpacity, AsyncStorage, ActivityIndicator, Image, StyleSheet } from 'react-native';
import { DrawerNavigator, DrawerItems, DrawerView, StackNavigator, TabNavigator, Header } from 'react-navigation';
import { HomeComponent } from "./Home/HomeComponent";
import { AboutusComponent } from "./Aboutus/AboutusComponent";
import { AnotherscreenWithouttabComponent } from "./AnotherscreenWithouttab";
import FeedAndSearchTab from "./feed/FeedAndSearchTab";
import { DetailsScreen1 } from "./Details/DetailsScreen1";
import { DetailsScreen2 } from "./Details/DetailsScreen2";
import * as css from "./Styles/Styles";
import { Button, Icon } from "react-native-elements";
//
// tabs
//
const nav_tab = TabNavigator(
// route config
{
DetailsRoute1: { screen: DetailsScreen1 },
DetailsRoute2: { screen: DetailsScreen2 },
},
// navigator config
{
lazy: true, // render the tabs lazily
tabBarPosition: 'bottom', // where are the tabs shown
backBehavior: 'none', // back button doesn't take you to the initial tab
tabBarOptions: css.tabs
},
);
//
// stack
//
export const AppNavigator = (isIntroRead = false, isSignedIn = false) => {
return StackNavigator(
// route config
{
HomeRoute: { screen: HomeComponent, path: 'home', }, // this is displayed first
AboutusRoute: { screen: AboutusComponent },
AnotherscreenWithouttabRoute: { screen: AnotherscreenWithouttabComponent , path: 'appointment/schedule', },
},
// navigator config
{
//headerMode: 'none', // this removes the navigation header
initialRouteName: isIntroRead ? 'HomeRoute' : 'IntroRoute', // HomeRoute /IntroRoute AppointmentScheduleRoute
navigationOptions: ({ navigation, screenProps }) => {
return {
headerTitle: <Title
navigation={navigation}
titleName={'Doctor On Call'}
/>, // label text // headerTitle: "Hi",
...css.header, // other styling
headerLeft: <TitleAndIcon navigation={navigation} />,
headerRight: <MenuIcon
navigation={navigation}
screenProps={screenProps}
/>,
header: (props) => <ImageHeader {...props} />,
}
},
cardStyle:{backgroundColor: '#FFFFFF', shadowOpacity: 0, shadowColor: 'transparent', }
}
);
};
//export default AppNavigator;

Categories

Resources