将屏幕标题更新为所选选项卡导航的标题

Update screen title to that of selected tab navigation

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

目前有两个问题无法解决,求指点。我正在使用 React Navigation v6.

  1. 单击我的任何选项卡导航器链接后,我注意到我的屏幕标题始终设置为“主页”。这可以更新到当前选择的选项卡吗?

  2. 使用抽屉链接时,上次单击的选项卡似乎保持其状态,旅程看起来像

我制作了一份小吃,希望能展示我面临的问题https://snack.expo.dev/@richlewis14/drawer-and-tab-navigation

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 会更改应用程序的某些行为,例如

Each navigator has its own options​. For example, specifying a title option in a screen nested in a child navigator won't affect the title shown in a parent navigator.

我们可以通过使用 react-native 的 official documentation 中提供的代码来解决此问题,以便根据 child 导航器状态设置 parent 屏幕选项。

以下是我为解决您的标题问题所做的工作。在 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]);

...

请注意,我们的 BottomTabNavigatorHome-Screen 的 Drawer 的 child,因此似乎两个导航器在更新时导航到同一屏幕彼此的导航状态。这是不可能的。我们可以看到这一点,如果我们通过抽屉导航到另一个屏幕,那么它的标题现在已经更新,但是屏幕保持不变。

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

感谢评论的讨论,这是可以接受的。解决你的第二个问题可以通过将 DrawerNavigator 中提供的 Home-screen 的道具 unmountOnBlur 设置为 true 来解决,如下所示。

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

请考虑我更新的 snack 以获得完整的工作解决方案。