How to combine tab and stack navigation props in reactnavigation typescript react native

1.6k views Asked by At

I am trying to combine two navigation props But I am not sure how to do this. Earlier when I used to define only one route I used to do something like this.

    export type MatrimonyStackRoutes = {
      Matrimony: undefined;
      GroomDetail: undefined;
    };
    
    
    export type MatrimonyStackNavigationProps<
      T extends keyof MatrimonyStackRoutes
    > = {
      navigation: StackNavigationProp<MatrimonyStackRoutes, T>;
      route: RouteProp<MatrimonyStackRoutes, T>;
    };
 <Stack.Navigator>
      <Stack.Screen name="Matrimony" component={MatrimonyTab} />
      <Stack.Screen name="GroomDetail" component={GroomDetail} />
    </Stack.Navigator>

And Inside component I used to declare like this

const Groom = ({ navigation }: MatrimonyStackNavigationProps<"Matrimony">) => {
  return (
    //////////
  );
};

This works fine But Now I am in need to combine two routes stack and bottomTab props show that I can use in my component in similar way. I am not sure how to do that any help would be great.

Here Is my Complete Code of both Tab And stack navigation when it is not combined

    export type MatrimonyTabRoutes = {
      Groom: undefined;
      Bride: undefined;
      Vendors: undefined;
    };
    export type MatrimonyStackRoutes = {
      Matrimony: undefined;
      GroomDetail: undefined;
    };
    
    
    export type MatrimonyStackNavigationProps<
      T extends keyof MatrimonyStackRoutes
    > = {
      navigation: StackNavigationProp<MatrimonyStackRoutes, T>;
      route: RouteProp<MatrimonyStackRoutes, T>;
    };
    export type MatrimonyTabNavigationProps<T extends keyof MatrimonyTabRoutes> = {
      navigation: BottomTabNavigationProp<MatrimonyTabRoutes, T>;
      route: RouteProp<MatrimonyTabRoutes, T>;
    };

const MatrimonyTab = ({}) => {
  const theme = useTheme();
  return (
    <Tab.Navigator
      tabBarOptions={{
        activeTintColor: theme.colors.primaryText,
        inactiveTintColor: theme.colors.grey,
        indicatorStyle: {
          backgroundColor: theme.colors.mainIconColor,
        },
      }}
    >
      <Tab.Screen name="Groom" component={Groom} />
      <Tab.Screen name="Bride" component={Bride} />
      <Tab.Screen name="Vendors" component={Vendors} />
    </Tab.Navigator>
  );
};

const MatrimonyStack = () => {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Matrimony" component={MatrimonyTab} />
      <Stack.Screen name="GroomDetail" component={GroomDetail} />
    </Stack.Navigator>
  );
};
1

There are 1 answers

1
Linda Paiste On

Your component still receives the same two standard props route and navigation but the navigation type is a little bit different when you are inside of both a stack and a tab navigator.

React Navigation includes a utility type CompositeNavigationProp specifically for the purpose of merging the navigation prop types.

The CompositeNavigationProp type takes 2 parameters, first parameter is the primary navigation type (type for the navigator that owns this screen, in our case the tab navigator which contains the Profile screen) and second parameter is the secondary navigation type (type for a parent navigator). The primary navigation type should always have the screen's route name as it's second parameter.

In your case, the primary navigator is the tab navigator and the secondary navigator is the stack. It is not required to set the route name for the secondary navigator, but in your case it is always "Matrimony" since all of the tabs are on the Matrimony screen.

export type TabScreenProps<T extends keyof MatrimonyTabRoutes> = {
  // combine the types for navigation
  navigation: CompositeNavigationProp<
    // the navigator which owns this screen comes first
    BottomTabNavigationProp<MatrimonyTabRoutes, T>,
    // the outer navigator comes second
    StackNavigationProp<MatrimonyStackRoutes, "Matrimony">
  >;
  // route props just depend on the inner navigator
  route: BottomTabScreenProps<MatrimonyTabRoutes, T>;
};

We use this type TabScreenProps to describe the props for the three tabs: Groom, Bride, and Vendors.

const Bride = ({ navigation, route }: TabScreenProps<"Bride">) => {
  /* ... */
};

Code Sandbox Demo