S.Neum
S.Neum

Reputation: 82

Separate Navigation in React Native Navigation

I'm currently figuring out how to reuse a navigation which is declared in it's own class for multiple screens or to put it in another way: If my approach isn't clever react wise, is there another, better way to create a navigation that is reused on multiple screens?

Whenever I'm trying to click a button in the navigation I get an error "undefined is not an object (evaluating _this2.props.navigation.navigate). So I guess that I'm missing something about this.props in the Navigation.js.

I'm using react-navigation because it has been recommended on SO and in the react-native documentation as the way to go.

App.js

import React from 'react';
import {createStackNavigator} from 'react-navigation';

import HomeScreen from './screens/home/HomeScreen'
import ProfileScreen from './screens/profile/ProfileScreen'
import SettingsScreen from './screens/settings/SettingsScreen'

const RootStack = createStackNavigator(
    {
        Home: HomeScreen,
        Profile: ProfileScreen,
        Settings: SettingsScreen,
    },
    {
        initialRouteName: 'Home',
    }
);

export default class App extends React.Component {
    render() {
         return <RootStack />;
    }
}

Navigation.js - contains the planned navigation for all screens

import React from 'react';
import {StyleSheet, View, TouchableOpacity, Text} from 'react-native';

class Navigation extends React.Component {

render() {
    return (
        <View style={navigationStyles.footerWrapper}>
            <View style={navigationStyles.footer}>

                <TouchableOpacity style={navigationStyles.footerItem}
                                  onPress={() => this.props.navigation.navigate('Home')}>
                    <Text style={navigationStyles.placeholderIcon}/>
                </TouchableOpacity>

                <TouchableOpacity style={navigationStyles.footerItem}
                                  onPress={() => this.props.navigation.navigate('Profile')}>
                    <Text style={navigationStyles.placeholderIcon}/>
                </TouchableOpacity>

                <TouchableOpacity style={navigationStyles.footerItem}
                                  onPress={() => this.props.navigation.navigate('Settings')}>
                    <Text style={navigationStyles.placeholderIcon}/>
                </TouchableOpacity>

            </View>
        </View>
    );
}
}

const navigationStyles = StyleSheet.create({
    //
});

module.exports = Navigation;

HomeScreen.js - screen that should contain the navigation but displays an error when the onPress event is fired

import React from 'react';
import {StyleSheet, View, TouchableOpacity, Text} from 'react-native';

import styles from '../../common/customStyleSheet'
import Navigation from '../../components/navigation/Navigation';


class HomeScreen extends React.Component {
    static navigationOptions = {
        title: 'Home',
        header: null,
};

render() {

    const {navigate} = this.props.navigation;

    return (
        <View style={styles.container}>
            <Text style={homeScreenStyles.paddingMedium}>HomeScreen.</Text>
            <Navigation/>
        </View>
    );
}
}

const homeScreenStyles = StyleSheet.create({
    paddingMedium: {
        paddingTop: 200,
    },
});

module.exports = HomeScreen;

Upvotes: 0

Views: 1094

Answers (1)

Jeremy
Jeremy

Reputation: 3748

your Navigation component won't automatically inherit the navigation prop from HomeScreen because it is just a subcomponent (it is not defined in the stack navigator like the HomeScreen is). So you need to pass the navigation as a prop to the Navigation component in your HomeScreen JSX.

// HomeScreen.js

render() {
  return (
      <View style={styles.container}>
          <Text style={homeScreenStyles.paddingMedium}>HomeScreen.</Text>
          <Navigation navigation={this.props.navigation}/>
      </View>
  );
}

Upvotes: 1

Related Questions