0

In my React Native app, I use react-navigation version 5.

How do I pass the navigation object to the scenes in BottomNavigation?

Here's the component where I create the BottomNavigation:

import React from 'react';
import { BottomNavigation } from 'react-native-paper';

// Components
import CodeScanner from '../../../screens/vendors/CodeScannerScreen';
import Home from '../../../screens/home/HomeScreen';
import Vendors from '../vendors/VendorsStack';
   
// Routes
const homeRoute = () => <Home />;
const vendorsRoute = () => <Vendors />;
const scanRoute = () => <CodeScanner />;

const HomeTabs = (props) => {
   
   const [index, setIndex] = React.useState(0);
   
   const [routes] = React.useState([
      { key: 'home', title: 'Home', icon: 'newspaper-variant-multiple' },
      { key: 'vendors', title: 'Vendors', icon: 'storefront' },
      { key: 'codescanner', title: 'Scan', icon: 'qrcode-scan' }
   ]);
   
   const renderScene = BottomNavigation.SceneMap({
      home: homeRoute,
      vendors: vendorsRoute,
      codescanner: scanRoute
   });

   return (
      <BottomNavigation
         navigationState={{ index, routes }}
         onIndexChange={setIndex}
         renderScene={renderScene}
         labeled={false} />
   );
}

export default HomeTabs;

In this code, I do have the navigation in the props but haven't been able to figure out a way to pass navigation to the screens. Please also note that the vendor one is actually a stack navigator. In particular, that's where I need access to navigation so that I can open up other screens.

Sam
  • 26,817
  • 58
  • 206
  • 383

3 Answers3

1

You should pass it from tabBar prop like below (I use TypeScript) and BottomTabBarProps:

export declare type BottomTabBarProps = BottomTabBarOptions & {
    state: TabNavigationState
    descriptors: BottomTabDescriptorMap
    navigation: NavigationHelpers<ParamListBase, BottomTabNavigationEventMap>
}

So you pass BottomTabBarProps to your custom tab component

<BottomTab.Navigator
    screenOptions={TabBarVisibleOnRootScreenOptions}
    initialRouteName={'Explore'}
    tabBar={(props: BottomTabBarProps) => <HomeTabs {...props} />}
>
    <BottomTab.Screen name="Explore" component={ExploreScreen} />
    ...
</BottomTab.Navigator>

So inner HomeTabs you got props.navigation

David Leuliette
  • 1,595
  • 18
  • 26
anthony willis muñoz
  • 2,346
  • 3
  • 16
  • 33
  • Thanks for your response but I think your response is for the BottomTabNavigator which is part of React Navigation. I'm actually using BottomNavigation by `react-native-paper`. I understand this is done in collaboration with React Navigation team but documentation is extremely poor and so far I haven't been able to figure out how to pass props/navigation. I'm actually thinking about switching to BottomTabNavigator too. It definitely has better documentation. – Sam Sep 21 '20 at 22:15
  • sorry didn't react about paper, well seems like better approach I read the docs as well and are really poor and hard to understand at all. – anthony willis muñoz Sep 21 '20 at 23:03
1

You may pass data to the vendors screen through the route like so:

const HomeTabs = ( props ) => {
  ...
  const [routes] = React.useState([
    ...
    { key: 'vendors', title: 'Vendors', icon: 'storefront', props: props },
    ...
  ]);
  ...
}

On your vendor screen you can then retrieve and use the data like this:

const VendorsRoute = ({ route }) => {
  const props = route.props;

  <Vendors />
}
0

I think you don't need to pass navigation to BottomNavigation. Because in react-navigation v5 navigation can access anywhere with hook Read this document https://reactnavigation.org/docs/connecting-navigation-prop/

Anhdevit
  • 1,926
  • 2
  • 16
  • 29
  • 1
    Actually in BottomNavigation you don't get access to useNavigation hook: "Note that you cannot use the useNavigation hook inside the tabBar since useNavigation is only available inside screens. You get a navigation prop for your tabBar which you can use instead" - https://reactnavigation.org/docs/bottom-tab-navigator/ – Bruinen Jan 12 '21 at 20:34