React Navigation V5 隐藏底部标签

React Navigation V5 Hide Bottom Tabs

我希望能够使用 React Native Navigation v5 隐藏屏幕上的选项卡。

我一直在阅读文档,但他们似乎没有为 v5 更新它,它指的是

这是我的代码:

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>
  );
}

我尝试过的事情:

  1. 访问函数的选项并以这种方式隐藏。
  2. 将 tabBarVisible 作为道具传递给屏幕。

我想问的是,在 React Navigation v5 中隐藏屏幕上的选项卡的正确方法是什么。

假设您想在进入“设置”时隐藏标签页。只需在构造函数中添加导航:

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

此代码应该有效。

您对此有 API 参考。 阅读:tabBarVisible

以上答案将帮助您从根目录中删除底部选项卡navigation.If您想从特定屏幕(如主屏幕或设置屏幕)中删除底部选项卡您需要动态更改导航选项。

要动态更改导航选项,您需要以下概念:

  • React.Context
  • useNavigationState

Context - 将动态更改 navigationOption 值,即是否隐藏底部选项卡。我们可以选择 MobX 或 Redux 来做同样的事情。

UseNavigationState - 将帮助上下文了解用户所在的屏幕。

我们需要在单独的 .js 文件中创建上下文,以便 Home.js 和 Settings.js 可以在所有其他屏幕中访问它。

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>
  );
}

这里的屏幕是一个标志,用于检查导航的索引并删除堆叠在 ProfileStackScreen 中的所有屏幕的底部导航。

使用 You Looking for Nested Screen Visible then Tab Bar Options Should be hide 而不是在 StackNavigator 函数中使用这个简单条件。

  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>
  );
}

我遇到了这个问题,即使在官方文档中也找不到解决方案(github 中的问题导致链接断开)经过一些试验和研究,我找到了适合我的解决方案 To从底部选项卡导航器组件实现它

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

希望对大家有所帮助!

您必须通过将 Tab Navigator 嵌套在 Stack Navigator 中来重构导航。按照此处的详细信息 hiding-tabbar-in-screens

这样,仍然可以在您的 Tab 导航器中嵌套一个 Stack Navigator。 SettingsStack

有了这个,当用户在设置屏幕和更新详细信息屏幕上时,标签栏是可见的,但在配置文件屏幕上,标签栏不可见。

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>
  );
}

按照文档的建议进行操作:https://reactnavigation.org/docs/hiding-tabbar-in-screens/

import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; // version 5.6.1
import { createStackNavigator } from "@react-navigation/stack"; // version 5.6.2

根据我的检查 navigation.routes.state.index 当你 navigation/push 到第二个屏幕时会有一个值所以我创建了一个函数

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

并在 BottomTab.Screen 选项中调用它

<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>

tabbarvisible-option-is-no-longer-present 在反应导航 v5 向上。您可以通过指定实现相同的行为 tabBarStyle: { display: 'none' } 在屏幕的选项中要隐藏底部选项卡

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>
  );
}