react-navigation / react-navigation

Routing and navigation for your React Native apps
https://reactnavigation.org
23.54k stars 5.02k forks source link

undefined is not an object(this.props.navigation) #4708

Closed mkloar closed 6 years ago

mkloar commented 6 years ago

The issue tracker is reserved for bug reports only.

I have 2 screens; 1st one is login 2nd one is Main with 2 bottom tabs (createBottomTabNavigator).

I want to navigate to 3rd screen from Main. I always get an error; undefined is not an object (evaluating this.props.navigation). My current code working only if i want to navigate to 3rd screen from some other component not primarely from Main tab in Main screen.

Current Behavior

My code in app.js

      const Routes = createStackNavigator(
      {
        Login: {
          screen: Login,

       navigationOptions: ({ navigation }) => ({
          header: null,
        }),

      },
      Main: {
       screen: MainScreenRoutes,
       navigationOptions: ({navigation}) => ({
         header: null,
       }),
     },
   },
   {
     initialRouteName: 'Main',
     headerMode: 'screen',
     navigationOptions: {
       ...HeaderStyles,
       animationEnabled: true
     }
   }
 );

My code in Main; routes;

let headerDefaultNavigationConfig = {
   header: props => <CustomHeader {...props} />,
   ...HeaderStyles
  };

  const Tab1 = createStackNavigator(
   {
     Domov: {
       screen: HomeScreen,
       navigationOptions: {
      },

     },
     /*MyProfil: {
      screen: MyProfil,
     }*/
   },
   {
      navigationOptions: ({ navigation }) => ({
       ...headerDefaultNavigationConfig
     }),
   }
 );

 const Tab2 = createStackNavigator(
   {
     Dnevnik: {
       screen: Diary,
       navigationOptions: {
         headerTitle: "Tab2",
         headerLeft: (
           <Text>Ok</Text>
         )
       },
     }
   },
   { 
     navigationOptions: ({ navigation }) => ({
       ...headerDefaultNavigationConfig
     }),

   }
 );

 const bottomTabs = createBottomTabNavigator(
 {
   Domov: Tab1,
   Dnevnik: Tab2,
 },
 {
   initialRouteName: "Domov",
   navigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ focused, tintColor }) => {
         const { routeName } = navigation.state;
         let iconName;
         if (routeName === 'Domov') {
          //iconName = `home${focused ? '' : '-outline'}`;
           iconName='home';
         } else if (routeName === 'Dnevnik') {
          //iconName = `ios-calendar${focused ? '' : '-outline'}`;
           iconName='ios-calendar';
         } 

         // if focused return view with line
         if(focused) {
           return (
             <View style={styles.item}>
                 <Icon name={iconName} style={{fontSize: 20, color: '#FFF'}} />
                 <View style={styles.line}></View>
             </View>
           );
         } else {
           return(
             <Icon name={iconName} style={{fontSize: 20, color: '#FFF'}} />
           )
         }

       },

     }),
     tabBarPosition: 'bottom',
     tabBarOptions: {
       activeTintColor: 'white',
       showLabel: false,
       inactiveTintColor: '#4C2601',
       style: {
         backgroundColor: '#033D51',
       },
       labelStyle: {
         fontSize: 12,
         lineHeight: 30,
       },
     },
     swipeEnabled: true,

 });

 const All = createStackNavigator(
 {
   "Home":{
     screen: bottomTabs,
     navigationOptions: {
         header: null,
     },
   },
   "MyProfil":{
     screen: MyProfil,
     navigationOptions: ({ navigation }) => ({
       ...headerDefaultNavigationConfig
     }),
   }, 
 },
 {
     initialRouteName: 'Home',
     headerMode: 'screen',
     navigationOptions: {
       ...HeaderStyles,
       animationEnabled: true
     }
 }

 );

 export default All;

My code for navigate to different screen in my Main screen;

export default class HomeScreen extends React.Component<Props> {

    constructor(props) {
        super(props);

     }

    static navigationOptions = {
        headerTitle: "Tab1",
        headerLeft: (
          <Text>Ok</Text>
        ),
        headerRight: (
          <View>
                    <TouchableOpacity
                        title="Ok" 
                        //onPress={ this.changeScreen.bind(this) }>
                        onPress={() => this.props.navigation.navigate('MyProfil')}>

                        <Text>Ok</Text> 
                    </TouchableOpacity>
          </View>
        )
     };
//other code...render etc...
`

Your Environment

software version
react-navigation ^2.6.2
react-native 0.55.2
node
npm or yarn
kirakik commented 6 years ago

Hi @mkloar, it's a difficult to parse through the code you posted, there seem to be some pieces missing. Could you try to replicate your issue in a Snack?

brentvatne commented 6 years ago

the problem is that you can't access props from navigationOptions - see https://reactnavigation.org/docs/en/header-buttons.html and notice how to access navigation in that context