45

I have the following stack navigation and screens:

export const HomeStack = createStackNavigator({
    Home: HomeScreen,
    Categories: CategoriesScreen,
    Products: ProductsScreen,
    ProductDetails: ProductDetailsScreen,
})

I want to hide tabs only in ProductDetailsScreen:

export const hideTabBarComponents = [
    'ProductDetails',
]

export const MainTabs = createBottomTabNavigator(
    {
        Home: HomeStack,
        Favorite: FavoriteScreen,
        Account: AccountScreen,
        Help: HelpScreen,
        Events: EventsScreen
    },
    {
        navigationOptions: ({ navigation }) => ({

            tabBarIcon: ({ focused, tintColor }) => {
                ...
            },
            tabBarLabel: ({ focused, tintColor }) => {
                ...
            },
            
            tabBarVisible: ! hideTabBarComponents.includes(navigation.state.routeName)

        }),
    }
);

The problem is that can't pass any options to Tab navigation from Stack Navigation

Not all of the stack screens only one of them

AmerllicA
  • 29,059
  • 15
  • 130
  • 154
Ahmad Abdullah
  • 1,645
  • 1
  • 16
  • 25

30 Answers30

66

This is how I hide the tab bar in a specific screen in a stack (React Nav 5.x & 6.x)

import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
const ProfileStack = createStackNavigator();
    
const ProfileNavigator = ({ navigation, route }) => {
        React.useLayoutEffect(() => {
            const routeName = getFocusedRouteNameFromRoute(route);
            if (routeName === "Group"){
                navigation.setOptions({tabBarVisible: false});
            }else {
                navigation.setOptions({tabBarVisible: true});
            }
        }, [navigation, route]);
        return(
            <ProfileStack.Navigator>
                <ProfileStack.Screen name="Profile" component={ProfileScreen} />
                <ProfileStack.Screen name="Group" component={GroupScreen} />
            </ProfileStack.Navigator>
        )};

If you guys have number of screens that need to hide the tabbar use a string array of those route names and hide tabbar if focused route name includes in that array

const tabHiddenRoutes = ["Group","Map"];

if(tabHiddenRoutes.includes(getFocusedRouteNameFromRoute(route))){
  navigation.setOptions({tabBarVisible: false});
 }else{
 navigation.setOptions({tabBarVisible: true});
}

[Edit] - In case of v6, use display because tabBarVisible is deprecated in the favour of tabBarStyle-

if(tabHiddenRoutes.includes(getFocusedRouteNameFromRoute(route))){
  navigation.setOptions({tabBarStyle: {display: 'none'}});
 } else {
 navigation.setOptions({tabBarStyle: {display: 'flex'}});
}
  • 2
    this is the best solution among the other solutions. a clever and efficient way to show and hide BottomTabBar. thanks a lot – nima Apr 14 '21 at 12:28
  • 1
    Winner winner chcken dinner! This is the solution ! – Rolando Niubó Jun 16 '21 at 02:36
  • 4
    I used this solution as well, but if you're coming from v6, instead of `navigation.setOptions({tabBarVisible: false});`, use `navigation.setOptions({tabBarStyle: {display: 'none'}});` – hellomello Aug 18 '21 at 02:28
  • 8
    For me sometimes, the behavior is inconsistent, The tab disappears but it leaves a display(exact size as the hidden bar with no content in it, just a grey background – Hilory May 24 '22 at 23:44
  • One potential advantage of this solution is that it keeps the screens related to the "ProfileStack" or the "ProfileFlow" all in one place. I personally like this better than ReactNavigation's recommendation which moves the related screens away from their associated stack. – jarrodparkes Jun 09 '22 at 16:32
  • 1
    I am using V6 and the last answer provided above worked for me. Great explanation. Thanks – Bhavnik Sep 23 '22 at 06:25
  • 2
    @Hilory did you manage to overcome your issue? I'm having a similar one, it seems to keep the bounding box of the navigation when I go into my next screen. Visually only. – Taylor Stocks Nov 11 '22 at 12:28
  • 1
    The edit for v6 works fine for hiding the tab bar but it messes up the navigation function for nested components, so when you call navigation.navigate() it navigates to undefined. I dont know but I just set the style to { height: 0, width: 0, opacity: 0 } and now navigation works – Cloyd Abad Mar 15 '23 at 13:18
64

To hide the tab bar in one of the screens, this works for React Navigation v4:

HomeStack.navigationOptions = ({ navigation }) => {

    let tabBarVisible = true;

    let routeName = navigation.state.routes[navigation.state.index].routeName

    if ( routeName == 'ProductDetails' ) {
        tabBarVisible = false
    }

    return {
        tabBarVisible,
    }
}

For v5, and v6 please check @Chathuranga Kasthuriarachchi's answer here

Ahmad Abdullah
  • 1,645
  • 1
  • 16
  • 25
30

For React Navigation 5, you can do this inside of the stack component:

props.navigation.dangerouslyGetParent().setOptions({
  tabBarVisible: false
});

https://reactnavigation.org/docs/en/navigation-prop.html#setoptions---update-screen-options-from-the-component

Be careful with using this though, you'll want to reset the tabBarVisible to true once unmounting the component.

For example, with React hooks inside the Stack component:

    useEffect(() => {
      const parent = props.navigation.dangerouslyGetParent();
      parent.setOptions({
        tabBarVisible: false
      });
      return () =>
        parent.setOptions({
          tabBarVisible: true
        });
    }, []);

Or you can reset the tabBarVisible in the Stack.Screen component with the back button press like this:

    const StackNav = (props) => (
      <Stack.Screen
        name='name'
        component={Name}
        options={{
          headerTitle: 'Name',
          headerLeft: () => (
            <Text
              onPress={() =>
                props.navigation.setOptions({
                tabBarVisible: true
                })
              }
            >
              on back
            </Text>
          )
        }}
      />
    }

(The second approach works better.)

Jordan Daniels
  • 4,896
  • 1
  • 19
  • 29
  • 1
    V5, If the root element is a Stack.screen nested in a Tab you need to access the parent as well on the root. Make use of the focus event so you don't have to make the tabBar visible again on unmount of stacked screen `useEffect(() => { const unsubscribe = navigation.addListener('focus', () => { // Screen was focused, this will execute when mounts and when a back button is pressed(returning to the screen) const parent = navigation.dangerouslyGetParent()!; parent.setOptions({ tabBarVisible: true, }); }); return unsubscribe; }, []);` – John Mar 26 '20 at 16:19
11

if you are using navigation 6 : Than The tabBarVisible option is no longer present. You can achieve the same behavior by specifying tabBarStyle: { display: 'none' } in options.

Paresh Shiyal
  • 534
  • 4
  • 15
8

first let's creat a stack navigator and call it StackHome

const StackHome = createStackNavigator(
{
 Home: Home,
 CustomHide: CustomHide,
});
// This code let you hide the bottom app bar when "CustomHide" is rendering
StackHome.navigationOptions = ({ navigation }) => {
 let tabBarVisible;
  if (navigation.state.routes.length > 1) {
navigation.state.routes.map(route => {
  if (route.routeName === "CustomHide") {
    tabBarVisible = false;
  } else {
    tabBarVisible = true;
  }
});
 }

 return {
   tabBarVisible
 };
};
export default StackHome;
OUBADI Ahmed
  • 132
  • 2
  • 4
4

If, like me, you struggled to make this work in React Navigation 6, here is how I achieved it... I had a bottomTabNavigator containing several stacks, and wanted to hide the tabbar on a specific screen (player) of the homestack

    import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
    ...
    
    <BottomTabNavigator.Screen 
         name="HomeStack" 
         component={HomeStack} 
         options={({route}) =>({ tabBarStyle: getTabBarStyle(route) })} />
    
    ....
    const getTabBarStyle = (route) => {  
      const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';
      let display = (routeName === 'Player') ? 'none':'flex';
      return {display}
    }
Miquel Ferrer
  • 51
  • 1
  • 1
3

With createBottomTabNavigator you can hide it with the defaultNavigationOptions

defaultNavigationOptions: {
  tabBarVisible: false,
},
3

The flow goes like this

import {
  getFocusedRouteNameFromRoute,
} from "@react-navigation/native";
<BottomTab.Navigator
      screenOptions={(props) => {
        console.log(getFocusedRouteNameFromRoute(props.route));
        return {
          tabBarActiveTintColor: Colors.Red,
          tabBarInactiveTintColor: Colors.Blue,
          headerShown: false,
          tabBarStyle: {
            display:
              getFocusedRouteNameFromRoute(props.route) === "ProdDetails"
                ? "none"
                : "flex",
          },
        };
      }}
    >
{...children}
</BottomTab.Navigator>

Cheers

FaysalB
  • 330
  • 1
  • 11
2

I achieved that in this way. First the hook:

import {useLayoutEffect} from 'react';
import {useNavigation, useRoute, getFocusedRouteNameFromRoute} from '@react-navigation/native';

export function useHiddenTabs (hiddenTabRoutesArray, fallbackRoute) {
  const navigation = useNavigation();
  const route = useRoute();

  useLayoutEffect(() => {
    const routeName = getFocusedRouteNameFromRoute(route) ?? fallbackRoute;
    navigation.setOptions({
      tabBarVisible: !hiddenTabRoutesArray.includes(routeName),
    })
  }, [navigation, route]);
}

And then usage:

import {getFocusedRouteNameFromRoute} from '@react-navigation/native';

const routesWithoutTabs = ['ScreenWithoutTabs'];

const StackComponent = ({navigation}) => {

  useHiddenTabs(routesWithHiddenTabs, 'FallbackRoute');

  return (
    <Stack.Navigator /* other props */>
      <Stack.Screen
        name='ScreenWithoutTabs'
        component={ScreenWithoutTabsComponent}
      />
    </Stack.Navigator>
  );
};

Corresponding docs

But probbaly you just need to consider to just redesign your routing tree. Maybe these screens just should be somewhere out of your tab navigator.

Aliaksei
  • 1,094
  • 11
  • 20
1

This is how I did. Select the stack in which you want to hide the tab bar. You can select it based on the index.

AppStack.navigationOptions = ({ navigation }) => {
  let tabBarVisible = true;
    if (navigation.state.index > 0) {
       tabBarVisible = false;
    }
    return {
       tabBarVisible
    };
};

Here is the link of the docs of React navigation

Pratap Sharma
  • 2,633
  • 2
  • 18
  • 32
1

const AppNavigation = createBottomTabNavigator( {

    Learning:
    {
        screen: LearningStack,
        navigationOptions: {
            tabBarLabel: 'Learning',
            // tabBarVisible: false,
            tabBarIcon: ({ tintColor, focused }) => (
                // <Icon name='terminal' size={25} color={Colors.white} />
                <Image
                    source={require('../assets/TabBarIcon/Learning_96px.png')}
                    style={{ width: 45, height: '90%', }}
                />
            ),

        }
    },

Learning

Stack.navigationOptions

= ({ navigation }) => {

    let tabBarVisible = false;

    let routeName = navigation.state.routes[navigation.state.index].routeName

    if (routeName == 'Learning') {
        tabBarVisible = true
    }

    return {
        tabBarVisible
    }
},

})

1

You can also create a Modal inside the screen and make it always visible, with something like this:

const Example = () => {
  return(
    <ScrollView>
      <Modal animationType="slide" transparent={true} visible={true} >
          <View style={styles.modalExample}>
          </View>
      </Modal> 
    </ScrollView>
  )
}

And then style it:

const styles = StyleSheet.create({
  modalExample: {
    height:"100%",
    width:"100%",
    backgroundColor: "#000000",
  },
})
1

Another way is to use the height of the tab bar to hide it. This is required when using createMaterialTopTabNavigator, since it does not have a tabBarVisible property. You can use a global state variable (Redux or UseState) or you can use something similar to the selected answer, where you keep track of the currently active screen.

Assuming 'hideTab' is a boolean.

const Tab = createMaterialTopTabNavigator();
...
<Tab.Navigator
   tabBarOptions={{style: {height: hideTab ? '0%' : null}}>
user2210411
  • 1,497
  • 1
  • 9
  • 7
1

The are multiple ways to do it in v5: 1. use tabBarVisible option based on specific strings/route names

using the useRoute() hook & setOptions({ tabBarVisible: false })

2. use dangerouslyGetParent() method for dynamic control For specific screen

navigation.dangerouslyGetParent()?.setOptions({ tabBarVisible: false })

On scrolling hide the bottom tab bar

const navigation = useNavigation();

const handleScroll = ({ nativeEvent: { contentOffset: { y = 0 }} }) => {
  navigation.dangerouslyGetParent()?.setOptions({ tabBarVisible: y <= 50 })
}

return (
  <ScrollView onScroll={handleScroll} scrollEventThrottle={16}>
    ...
  </ScrollView>
)

3. for simple nesting you can pass the "tab bar navigation" to any stack screen props

// navigation -> is the bottomTab navigation instance
export default ({ navigation }) => {
  return (
    <Stack.Navigator screenOptions={screenOptions}>
      <Stack.Screen name="Trips">
        // add a new prop named tabNavigation={navigation}
        // you also have access to the stack navigation
        {(props) => <Trips tabNavigation={navigation} {...props} />}
      </Stack.Screen>
      <Stack.Screen name="Trip" component={Trip} />
    </Stack.Navigator>
  );
}

and use the examples from point 2

tabNavigation?.setOptions({ tabBarVisible: false })
1

You can use the useFocusEffect hook to check if the screen is focused then hide the navigator with navigation.dangerouslyGetParent()

This is a custom hook I created:

import React from 'react';
import { useFocusEffect } from '@react-navigation/native';

const useHideTabBar = (navigation) => {

    useFocusEffect(
        React.useCallback(() => {

            // hide
            const parent = navigation.dangerouslyGetParent();
            parent.setOptions({
                tabBarVisible: false,
            });

            // reveal after changing screen
            return () =>
                parent.setOptions({
                    tabBarVisible: true,
                });

        }, []),
    );


};

export default useHideTabBar;
Paul Onteri
  • 577
  • 6
  • 11
1
<Navigator initialRouteName="Home"}>
    <Screen name="Home" component={Home} />
    <Screen
        name="About"
        component={About}
        options={{ tabBarStyle: { display: 'none' } }}
    />
</Navigator>
  • While code-only answers might answer the question, you could significantly improve the quality of your answer by providing context for your code, a reason for why this code works, and some references to documentation for further reading. From [answer]: _"Brevity is acceptable, but fuller explanations are better."_ – Pranav Hosangadi May 11 '22 at 16:19
1

just adding in screen options work for me

  tabBarButton: () => null,
OSMX
  • 47
  • 10
0

This is the solution that I used in my project.

I have a bottom tab navigator, with 2 routes: Home and Profile. The ProfileHomePage route brings to a stack navigation ProfileStackNavigation.

Then, in the ProfileStackNavigation, I have the ProfileHomePage where the bottom tab should appears, and other child pages, where the bottom tabs should not be visible. I added a param tabBarVisible: false in that pages.

Finally, in the MainTabNavigator ProfileHomePage route, I added the navigationOptions function, to test if the current route has the param tabBarVisible.

const ProfileStackNavigation = createStackNavigator(
  {
    ProfileHomePage: ProfileHomePage,
    AboutAppPage: {screen: AboutAppPage, params: {tabBarVisible: false}},
    DiaryPage: {screen: DiaryPage, params: {tabBarVisible: false}},
    FilesPage: {screen: FilesPage, params: {tabBarVisible: false}},
    NotificationsPage: {screen: NotificationsPage, params: {tabBarVisible: false}},
  },
  {
    initialRouteName: 'ProfileHomePage',
  },
);

const MainTabNavigator = createBottomTabNavigator(
  {
    HomePage: HomePage,
    ProfileHomePage: {
      screen: ProfileStackNavigation,
      navigationOptions: ({ navigation }) => {
        const {params = {}} = navigation.state.routes[navigation.state.index];
        const tabBarVisible = params.tabBarVisible === false ? params.tabBarVisible : true;
        return {
          tabBarVisible,
        }
      }
    },
  },
  {
    initialRouteName: 'HomePage',
    tabBarComponent: props => <AppFooterTab {...props} />,
  },
);
Marcelo Souza
  • 146
  • 1
  • 4
0

Another option here would be to add another stack navigator as a parent of the tab navigator, and put the screen that doesn't need the tab navigator there. This is the recommended way in versions of react navigation < 5

const FeedStack = createStackNavigator({
  FeedHome: FeedScreen,
  /* any other route you want to render under the tab bar */
});

const TabNavigator = createBottomTabNavigator({
  Feed: FeedStack,
  Profile: ProfileScreen,
});

const HomeStack = createStackNavigator({
  Tabs: TabNavigator,
  Details: DetailsScreen,
  /* any other route you want to render above the tab bar */
});

const AppNavigator = createSwitchNavigator({
  Auth: AuthScreen,
  Home: HomeStack,
});
fannolo
  • 357
  • 3
  • 10
  • Thank you @fannolo, this does not fit when you want to hide tabs for only one screen of your stack. – Ahmad Abdullah May 27 '20 at 04:10
  • @AhmadAbdullah actually in your case you can move ProductDetails and MainTabs in a new stack each at the same level: export const Stack = createStackNavigator({ Tabs: MainTabs, Details: ProductDetails }) – fannolo May 28 '20 at 07:51
0

try this code and it's will work:

  const getTabBarVisibility = (route) => {
const routName = route.state
  ? route.state.routes[route.state.index].name
  : '';
if (routName == 'chat') {
  return false;
} else {
  return true;
}

};

0
import React, {useLayoutEffect} from "react";
import { getFocusedRouteNameFromRoute } from '@react-navigation/native';

const MainStackNavigator = ({navigation, route}) => {
    useLayoutEffect(() => {
        const routeName = getFocusedRouteNameFromRoute(route);
        if (routeName === 'Details') {
            navigation.setOptions({tabBarVisible: false});
        }else {
            navigation.setOptions({tabBarVisible: true});
        }
    }, [navigation, route])
0

Easy solution as mentioned in react-navigation library, You can change the navigation structure react-navigation-doc

Bilal Yaqoob
  • 790
  • 1
  • 10
  • 22
0

REACT Native V6

I am using typescript and I encountered such an issue too. Since the tabBarVisible option is no longer available, I used the tabBarStyle instead and set the display property to 'none'.

Suppose I have two screens, the Home screen which is the tabbed screen and another screen say Side screen which is a Stacked screen where I want to hide the tab bar, then I do this in the Stacked screen navigator component:

const setTabStyleVisibility = (shouldBeVisible: boolean) =>
shouldBeVisible
  ? ({
      tabBarStyle: { display: 'flex' },
    } as Partial<BottomTabNavigationOptions>)
  : ({
      tabBarStyle: { display: 'none' },
    } as Partial<BottomTabNavigationOptions>);

I have a custom button defined as:

<Button title={btnTitle} onPress={onPressHandler}/>

On the Home Screen, I have a button which navigates to the Side screen and hides the tab by defining the custom onPressedHandler prop to the custom button as:

onPressHandler={() => {
    navigation.setOptions({
      ...setTabStyleVisibility(false),
    });
    navigation.navigate("Side");
  }}

Then I had a button passed to the next screen (Side screen) where the tab bar will be shown on going back to Home screen. I set the onPressedHandler which is a custom prop to the custom button to

onPressHandler={() => {
    navigation.setOptions({
      ...setTabStyleVisibility(true),
    });
    navigation.navigate("Home");
  }}
0
export const useHideTabsHook = () => {
const route = useRoute();
const navigation = useNavigation();
const tabHiddenRoutes = getHiddenRoutesForRoute(route.name);
useLayoutEffect(() => {
    const routeName = getFocusedRouteNameFromRoute(route);
    if (tabHiddenRoutes && tabHiddenRoutes.includes(routeName)) {
        navigation.setOptions({ tabBarStyle: { display: 'none' } });
    } else {
        navigation.setOptions({ tabBarStyle: { display: 'flex' } });
    }
}, [navigation, route, tabHiddenRoutes]);
};

write your own logic to get. the routes in each tab getHiddenRoutesForRoute

const getHiddenRoutesForRoute = routeName => {
switch (routeName) {
    case 'tab1':
        return tab1HiddenRoutes;
    case 'tab2':
        return tab2HiddenRoutes;
    default:
        return null;
}
};

Include this hook in each tab stack. this is using React-Navigation v6.

praveen seela
  • 538
  • 11
  • 24
0

Actually, by the docs explanation, it would be better to think deeply and re-arrange the screens to gather Tabbar screens underneath of TabStack and segregate the rest and especially the screens that you don't want to have Tabbar inside them, under the Navigation stack.

But if you want to hide the Tabbar in some sub-screens of a TabStack screen the following codes will be useful:

import { useNavigation } from '@react-navigation/native';

const Account = () => {
  const { getParent } = useNavigation();

  useEffect(() => {
    const parent = getParent();

    parent?.setOptions({
      tabBarStyle: { display: 'none' },
    });

    return () => {
      parent?.setOptions({
        tabBarStyle: { display: 'flex' },
      });
    };
  }, []);

  return (
    <View>
      ~~~

And I have created an useful custom hook for it:

import { useEffect } from 'react';
import useNavigation from './useNavigation';

const useHideTabBar = () => {
  const { getParent } = useNavigation();

  useEffect(() => {
    const parent = getParent();

    parent?.setOptions({
      tabBarStyle: { display: 'none' },
    });

    return () => {
      parent?.setOptions({
        tabBarStyle: { display: 'flex' },
      });
    };
  }, []);
};

export default useHideTabBar;
AmerllicA
  • 29,059
  • 15
  • 130
  • 154
  • This is not a good solution; you should read the react-navigation doc and think about correctly implementing your screen structure. – Ahmad Khani Jul 09 '22 at 07:28
  • @AhmadKhani, thanks, you're right, if you pay attention to the top of my answer, you would be abled to see I mentioned that, the true way is ordering the Stacks truly, but if in some rare case, if a developer wants to hide, she/he can use that awesome custom hook. – AmerllicA Jul 09 '22 at 09:33
  • This is a beautiful solution. – Sten Muchow Aug 09 '23 at 14:12
  • Thanks @StenMuchow, But I don't recommend it, please review your routing solution l, definitely there is another solution which isn't necessary to use this uncomfortable solution – AmerllicA Aug 09 '23 at 16:19
0

For Rect Navigation v6.x, I found 3 different methods to hide the tabBar from some screens. The following script demonstrates each of these methods. Credit goes to the various answers for this question.

// ///////// 
import { getFocusedRouteNameFromRoute, } from "@react-navigation/native";

const ShiftUpdateEmployerStack = (params) => {
    // Method#1: Hides the tabBar on the screen(s), which satisfy a certain condition (or all screens), in a "stack"
    React.useLayoutEffect(() => {
        // (1.a) Hide the tabBar on all screens in this stack: 
        // params.navigation.setOptions({ tabBarStyle: {display: "none"} });

        // OR (1.b) Hide the tabBar on the screens, which satisfy a certain condition 
        const routeName = getFocusedRouteNameFromRoute(params.route);
        if (routeName === "EmployerMenuScreen") { // the screen, which you want to hide the tabBar on
            params.navigation.setOptions({ tabBarStyle: {display: "none"} });
        } else {
            params.navigation.setOptions({ tabBarStyle: {display: "flex"} });
        }
    }, [params.navigation, params.route]);
    
    const MyStack = createNativeStackNavigator();

    return (
        <MyStack.Navigator>
            <MyStack.Screen name="SiteListScreen" component={SiteListScreen}/>
        </MyStack.Navigator>
    );
};

// ///////// 
const MainNavigator = () => { 
    const MyNav = createBottomTabNavigator(); 

    return (
        <MyNav.Navigator 

            // (Optional) Using a custom bottom tab bar, instead of the default one. If a custom tab bar is used, additional code is required (below)
            tabBar={params => <CustomTabBarContent {...params} />}

            // Method#2: Hides the tabBar on some screen(s) 
            screenOptions={(params) => {
                return { 
                    tabBarStyle: { display: (params.route.name === "ListShiftEmployerScreen" ? "none" : "flex") }, 
                }; 
            }}
        >
            {/* Method#3: Hides the tabBar on all screens in the "stack" */}
            <MyNav.Screen name="InitialStack" component={InitialStack} options={{ tabBarLabel: "Home", tabBarStyle: {display: "none"}, }} />
        </MyNav.Navigator>
    );
}; 

// ///////// Using a custom tabBar
const CustomTabBarContent = ({ state, descriptors, navigation, }) => {
    // If the option (tabBarStyle: { display: "none" }) is used anywhere, the following couple of statements are required
    const focusedOptions = descriptors[state.routes[state.index].key].options;
    if (focusedOptions?.tabBarStyle?.display === "none") {
        return null;
    }

    return (
    <View style={{ flexDirection: "row" }}>
        {state.routes.map((route, index) => {
            // more code...
            // see https://reactnavigation.org/docs/bottom-tab-navigator 
        })}
    </View>
    );
}; 
Bilal Abdeen
  • 1,627
  • 1
  • 19
  • 41
0

In my case i had a TabBar(Parent) and inside it StackNavigator(Parent 2) and then my DrawerNavigator.

that is the solution that worked for me on react-navigation 6:

import React from 'react';
import { useFocusEffect } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();

const MyStack = ({ navigation, route }) => {    
  useFocusEffect(
      React.useCallback(() => {
        const parent = navigation.getParent();
        if (route.name === 'myRouteName')
          parent.setOptions({ tabBarStyle: { display: 'none' } });
        else parent.setOptions({ tabBarStyle: { display: 'flex' } });
        return () => {
          parent.setOptions({ tabBarStyle: { display: 'flex' } });
        };
      }, [navigation, route]),
    );

  return (
    <Drawer.Navigator>
        <Drawer.Screen name="myRouteName"/>
    </Drawer.Navigator>
  );
};
0

If you're facing an issue where the TabBar leaves empty space while using @Chathuranga Kasthuriarachchi's solution, you can consider using position:absolute and controlling the bottom to hide it.

  const navigation = useNavigation();
    const route = useRoute();
    const tabBarHeight = useBottomTabBarHeight();
    const focusedName = getFocusedRouteNameFromRoute(route);

    const shouldHideTabBar =
      tabRoutes.includes(focusedName as RouterEnum) ||
      focusedName === undefined;

    useLayoutEffect(() => {
      navigation.setOptions({
        tabBarStyle: {
          position: "absolute",
          bottom: shouldHideTabBar ? 0 : -tabBarHeight,
        },
      });
    }, [route]);

make the Tab screen have a bottom padding

<Stack.Screen
            key={screen.name}
            name={screen.name}
            component={screen.component}
            options={{
              contentStyle: {
                 paddingBottom: shouldHideTabBar ? tabBarHeight : 0,
              },
            }}
          />

ref: https://reactnavigation.org/docs/bottom-tab-navigator/#tabbarstyle

Ace
  • 335
  • 3
  • 7
-1
const AppStack = createStackNavigator({
  SplashScreen: {
    screen: SplashScreen,
    navigationOptions: {
      header: null,
    },
  },
  Home: Home,
  CarouselMap: CarouselMap,
  HeatMapComponent: HeatMapComponent,
});
Dima Kozhevin
  • 3,602
  • 9
  • 39
  • 52
  • 2
    Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Mark Rotteveel Jul 26 '20 at 16:40
-2

this worked for me:

<BottomTab.Navigator
  screenOptions={{
    tabBarStyle: {
      display: isTabVisible ? 'flex' : 'none'
    }
  }}>

where isTabVisible is a global state variable.

Ariel Batista
  • 144
  • 1
  • 5