Search code examples
react-nativereact-navigationreact-navigation-stackreact-navigation-v5react-navigation-drawer

Making navigation available to all components in React Native app


I'm using React Navigation 5 in my React Native app and I'm not exactly clear about how to make navigation available to all components. I also want to mention that my app uses Redux for state management but I didn't integrate React Navigation with Redux -- maybe I should!

My App.js renders my Navigator.js component which looks like below. BTW, my app requires authentication and one of the key functions of the navigator function is to redirect unauthenticated users to login screen.

class Navigator extends Component {

   render() {
        return (
            <NavigationContainer>
                {
                   this.props.isAuthenticated
                   ? <MainMenuDrawer.Navigator drawerContent={(navigation) => <DrawerContent member={this.props.member} navigation={navigation} drawerActions={DrawerActions} handleClickLogOut={this.handleClickLogOut} />}>
                       <MainMenuDrawer.Screen name="Home" component={HomeStack} />
                       <MainMenuDrawer.Screen name="ToDoList" component={ToDoListStack} />
                     </MainMenuDrawer.Navigator>
                   : <SignInStack />
                }
            </NavigationContainer>
        );
      }
}

Then in my HomeStack, I have my Dashboard component which happens to be a class component that needs to access navigation. Here's my HomeStack:

const HomeStackNav = new createStackNavigator();

const HomeStack = () => {

   return(
      <HomeStackNav.Navigator screenOptions={{ headerShown: false }}>
         <HomeStackNav.Screen name="DashboardScreen" component={Dashboard} />
         <HomeStackNav.Screen name="SomeOtherScreen" component={SomeOtherComponent} />
      </HomeStackNav.Navigator>
   );
}

export default HomeStack;

Say, my Dashboard component looks like below. How do I make navigation available to this component?

class Dashboard extends Component {

   handleNav() {

      // Need to use navigation here...
   }

   render() {
      return (
         <Text>Welcome to Dashboard</Text>
         <Button onPress={() => this.handleNav()}>Go somewhere</Button>
      );
   }
}

function mapStateToProps(state) {
    return {
        member: state.app.member
    };
}

function mapDispatchToProps(dispatch) {

    return {
        actions: bindActionCreators(appActions, dispatch)
    };
}

export default connect(mapStateToProps, mapDispatchToProps)(Dashboard);

Do I need to pass navigation manually to each component? That seems too repetitive and prone to error. How do I make navigation available throughout my app?


Solution

  • Solution 1:

    you can use useNavigation hook for functional component

    import {useNavigation} from '@react-navigation/native';
    
    
    const navigation = useNavigation();
    
    navigation.navigate("interests");
    //or
    navigation.push("interests");
    
    

    Solution 2:

    you can use HOC withNavigation to navigation in props in any component for class component Ref

    you can install @react-navigation/compat by

    yarn add @react-navigation/compat
    

    You can import like below

    import { withNavigation } from '@react-navigation/compat';
    

    you can use withNavigation like below

    export default withNavigation(Dashboard)
    

    Note: then you can use this.props.navigation in Dashboard component