2

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?

Sam
  • 26,817
  • 58
  • 206
  • 383

1 Answers1

2

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

Muhammad Numan
  • 23,222
  • 6
  • 63
  • 80
  • Thank you for your response but isn't this a workaround? Doesn't the fact that `withNavigation` is part of the `@react-navigation/compat` package indicate we're not using the v5 API? Again, I appreciate your response. I just want to make sure I'm handling this right by v5 API standards. – Sam Jun 14 '20 at 17:21
  • yeah, you are using the right way. I just gave answer if you are unable to get navigation prop then you can get in any component like this – Muhammad Numan Jun 14 '20 at 17:26
  • You're right. Looks like we either use `withNavigation` that comes with the `@react-navigation/compat` package OR as per documentation, wrap a class component inside a functional one which seems strange, just to access the `navigation` object. `withNavigation` seems like a cleaner approach. Here's the docs: https://reactnavigation.org/docs/use-navigation/ – Sam Jun 14 '20 at 17:51
  • @Sam `useNavigation` is a hook which can be use only in functional component not in class base component – Muhammad Numan Jun 14 '20 at 17:57
  • 1
    Yes, I know. That's why the documentation suggests we wrap a class component inside a functional one -- see the link to docs -- which doesn't seem like a clean approach. That's why I said, `withNavigation` seems like a better solution. – Sam Jun 14 '20 at 18:01