Home > OS >  Passing props to Tab.Screen within BottomTabNavigator
Passing props to Tab.Screen within BottomTabNavigator

Time:12-20

I am running into difficulty passing props to one of my TabScreens using react-native's BottomTabNavigator. I have tried a couple of different options. Without props the Tab.Screen looks like this:

<Tab.Screen
  name='Visits'
  component={VisitsTab}
  options={{
    tabBarLabel: 'Visits',
    tabBarIcon: ({ color, size }) => <FontAwesome name='street-view' color={color} size={size} />,
  }}
/> 

So what I tried was this:

<Tab.Screen
  name='Visits'
  component={(props) => <VisitsTab {...props} />}
  options={{
    tabBarLabel: 'Visits',
    tabBarIcon: ({ color, size }) => <FontAwesome name='street-view' color={color} size={size} />,
  }}
/>

This still doesn't work, as the prop I am logging out in the VisitsTab is undefined - in other words, the VisitsTab is not receiving props. And to clarify, props is available in the MainScreen that passed on the props. What am I missing here?

By the way, I also tried this, but get the same issue:

  <Tab.Screen
    name='Visits'
    options={{
      tabBarLabel: 'Visits',
      tabBarIcon: ({ color, size }) => <FontAwesome name='street-view' color={color} size={size} />,
    }}
  >
    {(props) => <VisitsTab {...props} />}
  </Tab.Screen>

The full navigation for this bottom tab navigator looks like this:

import { VisitsTab } from './tabs/VisitsTab';
import { ChartTab } from './tabs/ChartTab';
import { GoalsTab } from './tabs/GoalsTab';

export const MainScreen = (props) => {
  const Tab = createBottomTabNavigator();
  return (
    <Tab.Navigator
      screenOptions={{
        headerShown: true,
        title: 'Patient',
        headerLeft: () => (
          <Feather
            name='chevron-left'
            size={24}
            onPress={() => props.navigation.goBack()}
          />
        ),
      }}
      initialRouteName={'Visits'}
    >
      <Tab.Screen
        name='Visits'
        component={(props) => <VisitsTab {...props} />}
        options={{
          tabBarLabel: 'Visits',
          tabBarIcon: ({ color, size }) => <FontAwesome name='street-view' color={color} size={size} />,
        }}
      />
      <Tab.Screen
        name='Chart'
        component={ChartTab}
        options={{
          tabBarLabel: 'Charts',
          tabBarIcon: ({ color, size }) => <FontAwesome name='id-badge' color={color} size={size} />,
        }}
      />
      <Tab.Screen
        name='Goals'
        component={GoalsTab}
        options={{
          tabBarLabel: 'Edit Goals',
          tabBarIcon: ({ color, size }) => <FontAwesome name='trophy' color={color} size={size} />,
        }}
      />
    </Tab.Navigator>
  );
};

By the way, somewhat frustratingly, the documentation page for the Bottom Tabs Navigator doesn't actually address how to pass props.

CodePudding user response:

Props for a component (for a screen to be precise) are not passed by the navigation framework. Props are passed from a parent to its child components. When writing component={Visits}, we do not instantiate an actual JSX components. Thus, there are no props to be passed.

In order to pass information during navigation, we use the route params. Here is an example: navigation.navigate("Visits", {x: 42}).

However, if Visits is supposed to be an initial screen of some navigator, then we have never actually navigated. Thus, the above approach does not help.

For this reason, the react-navigation framework added the initialParams prop for screens. They are defined inside the screen of some navigator.

 <Tab.Screen
        name='Visits'
        component={VisitsTab}
        initialParams={props}
      />

whereby props is any object and it might be better to use a different name, since these aren't actual props.

Then, access them in your screen.

function VisitsTab({route}) {
    const params = route?.params

    return (...)
}

We can access the passed information via params.

  • Related