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

标签 react-native react-navigation

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

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

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

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

  • 从主页开始(主屏幕渲染良好)
  • 单击用户个人资料选项卡(正常呈现用户个人资料页面)
  • 然后点击抽屉中的“预订新类(class)”(渲染新类(class)页面即可)
  • 然后单击抽屉中的“主页”(这将呈现用户个人资料屏幕)

我制作了一份零食,希望能解决我面临的问题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;

最佳答案

您正在将 Tab.Navigator 嵌套在 Drawer.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.

我们可以使用 official documentation 中提供的代码来修复此问题的react-native用于根据子导航器状态设置父屏幕选项。

以下是我为解决您的标题问题所做的操作。在 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 的子级,因此两个导航器似乎导航到相同的位置屏幕同时更新彼此的导航状态。这不可能。我们可以看到这一点,如果我们通过抽屉导航到不同的屏幕,那么它的标题现在会更新,但是屏幕保持不变。

如果用户位于主屏幕上,并且希望通过 Tab.Navigator 进行导航,以使两个导航器保持可见,则这是可能的。如果用户通过 Drawer 导航到与 Home 不同的屏幕,则 Tab.Navigator 将消失。

由于评论的讨论,这是可以接受的。通过将 DrawerNavigator 中提供的主屏幕的属性 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 - 将屏幕标题更新为所选选项卡导航的标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71184594/

相关文章:

ios - 将颜色列表从 Objective-C 传递到 React Native

ios - React-Native View Component 按钮按下时的原生 iOS 导航

javascript - 如何避免附加多个事件监听器?

reactjs - 以编程方式 react 导航更改选项卡顺序

react-native - React Navigation - 如何在 TabNavigator 中跨不同屏幕传递数据?

javascript - 缺少 Realm 构造函数 react native ios 但 Realm 已链接

javascript - React Native 将一个组件传递给另一个组件

react-native - 无法连接到 Android 模拟器上的开发服务器

react-native - react 导航以从 redux 操作文件中导航

react-native - react 导航和 Redux : All screens rerender using a StackNavigator when redux state is changed