Dimitri Kopriwa
Dimitri Kopriwa

Reputation: 14353

How to use useNavigation() within @react-navigation drawer?

Current Behavior

I have a react-native application that use react-navigation v5 for the routing.

  1. I have a drawer (offeset menu left) in all my views
  2. I use the stackNavigation for page transition.

Because of (1), my structure is drawerNavigator (a) > stackNavigator (b) > views (c).

When I try to call the useNavigation() hook within my <DrawerContent />, I have the following error:

Error: We couldn't find a navigation object. Is your component inside a navigator?
    at useNavigation (bundle.js:8766)

Yes, I am not inside the stackNavigator so the hook cannot be called

Expected Behavior

I expect to have navigation available within my <DrawerContent />.

Your Environment

| software                       | version |
| ------------------------------ | ------- |
| iOS or Android                 | iOS, Android and web
| @react-navigation/native       | 5.0.0-alpha.41
| @react-navigation/stack         | 5.0.0-alpha.63
| @react-navigation/drawer       | 5.0.0-alpha.41
| react-native-reanimated        | 1.4.0
| react-native-gesture-handler   | 1.5.3
| react-native-safe-area-context | 0.6.2
| react-native-screens           | 2.0.0-alpha.32
| react-native                   | https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz
| expo                           | SDK36
| node                           | v13.5.0
| npm or yarn                    | 6.13.7

How can I use @react-navigation/stack inside @react-navigation/drawer or how should I build my drawer and app with them?

Upvotes: 8

Views: 24525

Answers (4)

samthui7
samthui7

Reputation: 943

I'm also using React Navigation 5x, I followed this guide and still succeed using first approach (for old RNavigation). Details: mock the useNavigation function

jest.mock(‘react-navigation-hooks’, () => ({
 useNavigation: () => jest.fn(),
 useNavigationParam: jest.fn(jest.requireActual(
  'react-navigation-hooks'
 ).useNavigationParam),
}));

Upvotes: 2

Karan
Karan

Reputation: 285

You can follow this video in here - https://youtu.be/hLP1G29bbLU

You can see the usage of useNavigation hook in the video.

Upvotes: 0

hong developer
hong developer

Reputation: 13906

You don't have to use useNavigation if you're on a screen in the Navigator.

The structure of the navigator is as follows.

  • stackNavigator
    • drawerNavigator
      • drawerScreens
  • stackScreens

The screen movement is as follows.

Example

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button
        onPress={() => navigation.navigate('moveScreenName')}
        title="Go to moveScreenName"
      />
    </View>
  );
}

useNavigation is a hook which gives access to navigation object. It's useful when you cannot pass the navigation prop into the component directly, or don't want to pass it in case of a deeply nested child.

useNavigation() returns the navigation prop of the screen it's inside.

Example

function MyBackButton() {
  const navigation = useNavigation();

  return (
    <Button
      title="Back"
      onPress={() => {
        navigation.goBack();
      }}
    />
  );
}

Upvotes: 1

Dimitri Kopriwa
Dimitri Kopriwa

Reputation: 14353

This is possible using https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html

Create RootNavigation :

import { createRef } from 'react';

export const navigationRef = createRef();

export function navigate(name, params) {
  navigationRef.current?.navigate(name, params);
}

export function goBack() {
  navigationRef.current?.goBack();
}

In App.js:

import { navigationRef } from './navigation/RootNavigation';
// ...
<NavigationContainer
  ref={navigationRef}
>
  {children}
</NavigationContainer>

Then import RootNavigation from any source and you will not have to worry about the react tree.

Upvotes: 14

Related Questions