最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Navigation V5 Hide Bottom Tabs - Stack Overflow

programmeradmin1浏览0评论

I would like to be able to hide the tabs on a screen using React Native Navigation v5.

I've been reading the documentation but it doesn't seem like they've updated this for v5 and it refers to the < v4 way of doing things.

here is my code:

import Home from './components/Home';
import SettingsScreen from './components/Settings';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createStackNavigator } from '@react-navigation/stack';

const SettingsStack = createStackNavigator();
const ProfileStack  = createStackNavigator();

function SettingsStackScreen() {
    return (
        <SettingsStack.Navigator>
            <SettingsStack.Screen name="Settings" component={SettingsScreen} />
        </SettingsStack.Navigator>
    )
}

function ProfileStackScreen() {
    return (
        <ProfileStack.Navigator>
            <ProfileStack.Screen name="Home" component={Home} />
        </ProfileStack.Navigator>
    )
}

const Tab = createBottomTabNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="Home" component={ProfileStackScreen} />
        <Tab.Screen name="Settings" component={SettingsStackScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

Things I have tried:

  1. Accessing the options of the function and hiding that way.
  2. Passing tabBarVisible as a prop to the Screen.

What I am asking for is, what is the correct way of hiding tabs on screens in React Navigation v5.

I would like to be able to hide the tabs on a screen using React Native Navigation v5.

I've been reading the documentation but it doesn't seem like they've updated this for v5 and it refers to the < v4 way of doing things.

here is my code:

import Home from './components/Home';
import SettingsScreen from './components/Settings';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createStackNavigator } from '@react-navigation/stack';

const SettingsStack = createStackNavigator();
const ProfileStack  = createStackNavigator();

function SettingsStackScreen() {
    return (
        <SettingsStack.Navigator>
            <SettingsStack.Screen name="Settings" component={SettingsScreen} />
        </SettingsStack.Navigator>
    )
}

function ProfileStackScreen() {
    return (
        <ProfileStack.Navigator>
            <ProfileStack.Screen name="Home" component={Home} />
        </ProfileStack.Navigator>
    )
}

const Tab = createBottomTabNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="Home" component={ProfileStackScreen} />
        <Tab.Screen name="Settings" component={SettingsStackScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

Things I have tried:

  1. Accessing the options of the function and hiding that way.
  2. Passing tabBarVisible as a prop to the Screen.

What I am asking for is, what is the correct way of hiding tabs on screens in React Navigation v5.

Share Improve this question asked Feb 17, 2020 at 17:03 Ash._Ash._ 3741 gold badge3 silver badges16 bronze badges
Add a comment  | 

11 Answers 11

Reset to default 6

tabbarvisible-option-is-no-longer-present in react navigation v5 upwards. You can achieve the same behavior by specifying tabBarStyle: { display: 'none' } in options of the screen you want to hide bottom tab

export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="Home" component={ProfileStackScreen} />
        <Tab.Screen options={{tabBarStyle:{display:'none'}}} name="Settings" component={SettingsStackScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

Let's suppose that you want to hide tabs when you are entering Settings. Just add navigation in your constructor:

function SettingsStackScreen({ navigation }) {
    navigation.setOptions({ tabBarVisible: false })
    return (
        <SettingsStack.Navigator>
            <SettingsStack.Screen name="Settings" component={SettingsScreen} />
        </SettingsStack.Navigator>
    )
}

This code should work.

You will have to restructure your navigation by having your Tab Navigator nested in the Stack Navigator. Following the details here hiding-tabbar-in-screens

This way it's still also possible to have a Stack Navigator nested in yourTab Navigator. SettingsStack

With this when the user is on the Setting screen and also the Update detail screen, the tab bar is visible but on the Profile screen, the tab bar is not.

import Home from './components/Home';
import Settings from './components/Settings';
import UpdateDetails from './components/UpdateDetails';
import Profile from './components/Profile';

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();
const StackSettings = createStackNavigator();
const Tab = createBottomTabNavigator();

function SettingsStack() {
    return (
        <StackSettings.Navigator>
            <StackSettings.Screen name="Settings" component={Settings} />
            <StackSettings.Screen name="UpdateDetails" component={UpdateDetails} />
        </StackSettings.Navigator>
    )
}

function HomeTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={Home} />
      <Tab.Screen name="Settings" component={SettingsStack} />
    </Tab.Navigator>
  );
}


export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeTabs} />
        <Stack.Screen name="Profile" component={Profile} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

I had this issue and couldn't find solution even in official docs ( the issues in github resulted to broken links) after some trials and research I found a solution for me To make it happen from the bottom tab navigator component

<Tab.Navigator tabBarOptions={stackOptions} >
  <Tab.Screen
    name={"market"}
    component={MarketNavigator}
    options={navigation => ({
      // tabBarIcon: ,
      tabBarVisible: navigation.route.state.index > 0 ? false : true
    })}
  />
</Tab.Navigator>

Hope it helps someone!

2022 Answer - How to hide Bottom Tabs in React Navigation V6

Step 1 - Hiding tab bar in specific screens

Sometimes we may want to hide the tab bar in specific screens in a native stack navigator nested in a tab navigator. Let's say we have 5 screens: Home, Feed, Notifications, Profile and Settings, and your navigation structure looks like this:

function HomeStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Home" component={Home} />
      <Stack.Screen name="Profile" component={Profile} />
      <Stack.Screen name="Settings" component={Settings} />
    </Stack.Navigator>
  );
}

function App() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={HomeStack} />
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen name="Notifications" component={Notifications} />
    </Tab.Navigator>
  );
}

With this structure, when we navigate to the Profile or Settings screen, the tab bar will still stay visible over those screens.

Step 2 - Solution to Hide Bottom Tabs

Now if we want to show the tab bar only on the Home, Feed and Notifications screens, but not on the Profile and Settings screens, we'll need to change the navigation structure. The way to achieve this is to nest the BottomTabs() as the first route of the stack.

Move your Tabs into a separate function BottomTabs()...

Other routes should be in the main App.js return function...

Make "BottomTabs" the First Route as seen below under the App() return function...

<Stack.Screen name="BottomTabs" component={BottomTabs} />

function BottomTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={Home} />
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen name="Notifications" component={Notifications} />
    </Tab.Navigator>
  );
}

function App() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="BottomTabs" component={BottomTabs} />
      <Stack.Screen name="Profile" component={Profile} />
      <Stack.Screen name="Settings" component={Settings} />
    </Stack.Navigator>
  );
}

After re-organizing the navigation structure, now if you navigate to the Profile or Settings screens, the bottom tab bar won't be visible over the screen anymore.

The above answer will help you to remove the bottom tabs from the root navigation.If you want to remove bottom tabs from a specific screen like Home Screen or Settings Screen you need to change navigation options dynamically.

For changing navigation options dynamically you will need the concept of:

  • React.Context
  • useNavigationState

Context - will dynamically change the navigationOption value i.e. either to hide the bottom Tabs or not. We can choose MobX or Redux to do the same.

UseNavigationState - will help context to know at which screen the user is.

We need to create Context in a separate .js file so that Home.js and Settings.js can access it in all the other screens.

import * as React from 'react';
import { View, Text } from 'react-native'
import { NavigationContainer, useNavigationState, useRoute } from '@react-navigation/native';
const Tab = createBottomTabNavigator();
const Context = React.createContext();

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createStackNavigator } from '@react-navigation/stack';
import { TouchableOpacity } from 'react-native-gesture-handler';


const SettingsStack = createStackNavigator();
const ProfileStack = createStackNavigator();

function SettingsScreen({ navigation }) {
  return (
    <View>
      <Text>
        Setting
      </Text>
    </View>
  );
}

function Home({ navigation }) {
  const rout = useNavigationState(state => state);
  const { screen, setScreen } = React.useContext(Context);
  setScreen(rout.index);
  return (
    <View>
      <TouchableOpacity
        onPress={() => {
          navigation.navigate("Settings");
        }}
      >
        <Text>
          Home
        </Text>
      </TouchableOpacity>
    </View>
  );
}

function SettingsStackScreen({ navigation }) {
  return (
    <SettingsStack.Navigator>
      <SettingsStack.Screen name="Settings" component={SettingsScreen} />
    </SettingsStack.Navigator>
  )
}

function ProfileStackScreen({ navigation }) {
  const { screen, setScreen } = React.useContext(Context)
  if (screen == 0) {
    navigation.setOptions({ tabBarVisible: true })
  } else {
    navigation.setOptions({ tabBarVisible: false })
  }
  return (
    <ProfileStack.Navigator>
      <ProfileStack.Screen name="Home" component={Home} />
      <ProfileStack.Screen name="Settings" component={SettingsScreen} />
    </ProfileStack.Navigator>
  )
}

function BottomNav({ navigation }) {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={ProfileStackScreen} />
      <Tab.Screen name="Settings" component={SettingsStackScreen} />
    </Tab.Navigator>
  );
}


export default function App() {
  const [screen, setScreen] = React.useState(0);

  return (
    <Context.Provider value={{ screen, setScreen }}>
      <NavigationContainer>
        <BottomNav />
      </NavigationContainer>
    </Context.Provider>
  );
}

Here the screen is a flag that checks the index of the navigation and removes the bottom navigation for all the screen stacked in ProfileStackScreen.

Use You Looking for Nested Screen Visible then Tab Bar Options Should be hide than Use this Simple Condition in StackNavigator Funtions.

  function HistoryStack({navigation, route}) {
if (route.state.index === 0) {
 navigation.setOptions({tabBarVisible: true});
 } else {
 navigation.setOptions({tabBarVisible: false});
}
return (
<Historys.Navigator initialRouteName={Routes.History}>
  <Historys.Screen
    name={Routes.History}
    component={History}
    options={{headerShown: false}}
  />
  <Historys.Screen
    name={Routes.HistoryDetails}
    component={HistoryDetails}
    options={{headerShown: false}}
  />
</Historys.Navigator>
  );
}
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; // version 5.6.1
import { createStackNavigator } from "@react-navigation/stack"; // version 5.6.2

From my inspection navigation.routes.state.index will have a value when you navigation/push to a second screen so I create a function

const shouldTabBarVisible = (navigation) => {
  try {
    return navigation.route.state.index < 1;
  } catch (e) {
    return true;
  }
};

and call it in BottomTab.Screen options

<BottomTab.Navigator
    initialRouteName='Home'
    tabBarOptions={{
        activeTintColor: "#1F2B64",
        showLabel: false,
    }}
>
    <BottomTab.Screen
        name='Home'
        component={HomeNavigator}
        options={(navigation) => ({
            tabBarIcon: ({ color }) => <TabBarIcon name='home' color={color} />,
            tabBarVisible: shouldTabBarVisible(navigation),
        })}
    />
</BottomTab.Navigator>

Restructure your navigation by having your Tab Navigator nested inside the Stack Navigator. Official documentation hiding-tabbar-in-screens

On following this approach, you have an advantage of showing same screen on all tabs which saves up some memory

Try out on snack

function HomeTabs() {
 return (
  <Tab.Navigator>
   <Tab.Screen name="Home" component={Home} />
   <Tab.Screen name="Feed" component={Feed} />
   <Tab.Screen name="Notifications" component={Notifications} />
  </Tab.Navigator>
 );
}

function App() {
 return (
  <NavigationContainer>
   <Stack.Navigator>
    <Stack.Screen name="Home" component={HomeTabs} />
    <Stack.Screen name="Profile" component={Profile} />
    <Stack.Screen name="Settings" component={Settings} />
   </Stack.Navigator>
 </NavigationContainer>
 );
}

You have API reference exactly for this. Read: tabBarVisible

just follow as what the documentation suggests: https://reactnavigation.org/docs/hiding-tabbar-in-screens/

发布评论

评论列表(0)

  1. 暂无评论