我正在用我的应用程序中的嵌套选项卡导航实现抽屉导航.

目前,我有两个问题到目前为止还无法解决,我正在寻找解决的方法.我使用的是React Navigation v6.

  1. 单击任何选项卡导航器链接时,我注意到我的屏幕标题总是设置为"主页".是否可以将其更新到当前选定的选项卡?

  2. 当使用抽屉链接时,最后一次单击的选项卡似乎保持其状态,旅程如下所示

  • 从主页开始(渲染主屏幕)
  • 单击用户配置文件选项卡(呈现用户配置文件页面)
  • 然后从抽屉中点击"预订新课程"(新课程页面显示为罚款)
  • 然后从抽屉中单击"主页"(这将显示用户配置文件屏幕)

我制作了一种零食,希望能展示我面临的问题

DrawerNavigator.js

import React, {useContext} from 'react';
import CustomDrawer from '../components/CustomDrawer.js';
import {BookNewEvent} from '../screens/events/BookNewEvent.js';
import {UserProfile} from '../screens/profile/UserProfile.js';

import BottomTabNavigator from '../navigation/BottomTabNavigator.js';
import {createDrawerNavigator} from '@react-navigation/drawer';
import Ionicons from 'react-native-vector-icons/Ionicons';

const Drawer = createDrawerNavigator();

const DrawerNavigator = ({navigation}) => {
  return (
    <Drawer.Navigator
      drawerContent={props => <CustomDrawer {...props} />}
      screenOptions={{
        drawerActiveBackgroundColor: '#2B6EB5',
        drawerActiveTintColor: '#fff',
        drawerInactiveTintColor: '#333',
        drawerLabelStyle: {marginLeft: -25, fontSize: 15},
      }}>
      <Drawer.Screen
        name="Home"
        component={BottomTabNavigator}
        options={{
          title: 'Home',
          drawerIcon: ({color}) => <Ionicons name="home" size={22} color={color} />,
        }}
      />
      <Drawer.Screen
        name="BookNewEvent"
        component={BookNewEvent}
        options={{
          title: 'Book Class',
          drawerIcon: ({color}) => <Ionicons name="calendar-outline" size={22} color={color} />,
      }}
    />
    </Drawer.Navigator>
  );
};
export default DrawerNavigator;

BottomTabNavigator.js

import React, {useContext} from 'react';

import {UserLandingPage} from '../screens/landing/UserLandingPage.js';
import {BookNewEvent} from '../screens/events/BookNewEvent.js';
import {UserProfile} from '../screens/profile/UserProfile.js';


import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Ionicons from 'react-native-vector-icons/Ionicons';

const Tab = createBottomTabNavigator();
const Stack = createNativeStackNavigator();

const UserHomeStack = () => {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={UserLandingPage}
        options={{headerShown: false}}
      />
    </Stack.Navigator>
  );
};


const BottomTabNavigator = ({navigation}) => {
  return (
    <Tab.Navigator
      screenOptions={{
      headerShown: false,
      tabBarShowLabel: false,
    }}>
      <Tab.Screen
        name="Home2"
        component={UserHomeStack}
        options={{
          tabBarIcon: () => <Ionicons name="home" size={22} />,
        }}
      />
      <Tab.Screen
        name="UserBookNewEvent"
        component={BookNewEvent}
        options={{
          tabBarIcon: () => <Ionicons name="add-circle" size={22} />,
        }}
      />
      <Tab.Screen
        name="UserProfilePage"
        component={UserProfile}
        options={{
          tabBarIcon: () => <Ionicons name="person" size={22} color="black" />,
        }}
      />
    </Tab.Navigator>
  );
};
export default BottomTabNavigator;

推荐答案

你正在Drawer.Navigator中嵌套Tab.Navigator.将其与零食中的以下代码片段进行比较.

<Drawer.Screen
          name="Home"
          component={BottomTabNavigator}
          options={{
            title: 'Home',
            drawerIcon: ({color}) => <Ionicons name="home" size={22} color={color} />,
          }}
 />

这不是问题,但您需要记住,nesting navigators改变了应用程序的某些行为,例如:.

每个导航器都有自己的选项​.

我们可以通过使用react native official documentation中提供的代码来解决这个问题,该代码用于根据子导航器状态设置父屏幕选项.

以下是我为解决你的头衔问题所做的工作.BottomTabNavigator.js年:

const BottomTabNavigator = ({navigation, route}) => {

function getHeaderTitle(route) {
  const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';

  switch (routeName) {
    case 'Home2':
      return 'Home';
    case 'UserBookNewEvent':
      return 'Book Class';
    case 'UserProfilePage':
      return 'Profile';
  }
}

React.useLayoutEffect(() => {
    navigation.setOptions({ headerTitle: getHeaderTitle(route) });
  }, [navigation, route]);

...

请注意,对于Home屏幕,我们的BottomTabNavigatorDrawer的子屏幕,因此两个导航器似乎都导航到同一屏幕,同时更新彼此的导航状态.这是不可能的.我们可以看到这一点,如果我们通过抽屉导航到另一个屏幕,那么它的标题现在会更新,但是屏幕保持不变.

如果用户在Home屏幕上,希望通过Tab.Navigator导航,以便两个导航器都保持可见,则这是可能的.如果用户通过Drawer导航到与Home屏幕不同的屏幕,则Tab.Navigator屏幕将消失.

感谢 comments 中的讨论,这是可以接受的.解决你的第二个问题可以通过一点小技巧来完成,将DrawerNavigator中提供的主屏幕的props unmountOnBlur设置为true,如下所示.

<Drawer.Screen
          name="Home"
          component={BottomTabNavigator}
          options={{
            title: 'Home',
            unmountOnBlur:true,
            drawerIcon: ({color}) => <Ionicons name="home" size={22} color={color} />,
          }}
 />

请考虑我的更新snack的完整工作解决方案.

React-native相关问答推荐

如何在Reaction Native DrawerNavigation中添加注销功能

构建 iOS Expo 应用时出现 React-Native xcodebuild 错误 65

单击react 本机时如何从同一屏幕更改内容

使用 Auth Token 标头react 本机图像,如何处理 401?

将值从一个 js 文件传递​​到 react native 中的另一个 js 文件:react native

使用 React Native 下载数据文件以供离线使用

判断状态对象是否为空

react-native (expo)加载markdown 文件

React-native 组件的 elevation样式导致的阴影

命令失败:gradlew.bat installDebug error whenever installing dependencies like navigation, firebase, icons etc in React-Native

如何在 React Native 中将静态图像拉伸为背景?

渲染时获取未定义不是 React Native 中的对象

如何将时刻日期转换为字符串并删除时刻对象

如何使 react-native Picker 停留在新 Select 的选项?

React Navigation 中的选项卡导航器图标

在不使用 3rd 方库的情况下,在react-native中显示主屏幕之前显示启动画面

ReactNative TextInput 不可见 iOS

Jest TransformIgnorePatterns 所有 node_modules 用于 React-Native Preset

开始滚动时使 TouchableOpacity 不突出显示元素

如何在 Android 手机上运行 React Native 应用程序