Home > Mobile >  Pass navigation in props to menu element in React Native and React Navigation
Pass navigation in props to menu element in React Native and React Navigation

Time:09-09

I'm adding a menu to every screen navigation header, so created a menu function that needs the navigation object to navigate to different screens based on the menu item tapped. But the navigation.navigate from props is undefined.

export default function GeneralMenu(props) {
    const [showMenu, setShowMenu] = useState(false);

  return (
    <View style={{}}>
      <Menu
        visible={showMenu}
        onDismiss={() => setShowMenu(false)}
        anchor={
          <TouchableOpacity onPress={() => setShowMenu(true)}>
            <MaterialCommunityIcons
              name="menu"
              size={30}
              style={{ color: 'white' }}
            />
          </TouchableOpacity>
        }>
        <Menu.Item onPress={() => { console.log(props.navigation)}} title="Screen1" />
        <Menu.Item onPress={() => {props.navigation.navigate('Screen1', {})}} title="Screen1" />
      </Menu>
    </View>
  );

Then I use it like this:

return (
    <Provider>    
        <NavigationContainer>
          
          <Stack.Navigator>
            <Stack.Screen
              name="Home"
              component={HomeComponent}
              options={{ title: 'Home',
                headerTitleAlign: 'center',
                headerTintColor: '#fff',
                headerStyle: {
                  backgroundColor: 'red'
                },
                headerRight: (navigation) => <GeneralMenu navigation={navigation} />,
              }}
            />
            ... 
            ...
        </NavigationContainer>
    </Provider>
);

The console.log() when first menu item is tapped shows:

Object {
  "canGoBack": false,
  "tintColor": "#fff",
}

As you see there is no navigate property. Please, any idea what I'm doing wrong?

CodePudding user response:

To get navigation.navigate() you would wanna use the function syntax of options, which receives an object that contains navigation, like so:

<Stack.Screen
  name="Home"
  component={HomeComponent}
  options={({ navigation }) => ({
    title: "Home",
    headerTitleAlign: "center",
    headerTintColor: "#fff",
    headerStyle: {
      backgroundColor: "red",
    },
    headerRight: () => <GeneralMenu navigation={navigation} />,
  })}
/>

CodePudding user response:

I'm not sure why you are passing navigation through props. But for react-navigation to navigate to other screens (even from the components that are not screen themselves), you don't need to pass them through props.

You can basically access navigation object itself by using useNavigation hook like this:

const navigation = useNavigation();

and then wherever you need to use it, you can use it normally like:

navigation.navigate(Screen name goes here);

CodePudding user response:

its happen because u shadowing name props, it should be

<Menu.Item onPress={() => { console.log(props.navigation)}} title="Screen1" />

<Menu.Item onPress={() => {props.navigation.navigate('Screen1', {})}} title="Screen1" />

Also

header right doesn't have navigation props It should be like this

return (
    <Provider>    
        <NavigationContainer>
          
          <Stack.Navigator>
            <Stack.Screen
              name="Home"
              component={HomeComponent}
              options={(navigation) => {
return { title: 'Home',
                headerTitleAlign: 'center',
                headerTintColor: '#fff',
                headerStyle: {
                  backgroundColor: 'red'
                },
                headerRight: () => <GeneralMenu navigation={navigation} />,
              }
}}
            />
            ... 
            ...
        </NavigationContainer>
    </Provider>
);
  • Related