覆盖标题标题React Navigation V5

时间:2020-05-05 08:49:26

标签: reactjs react-native react-navigation

我在堆栈导航器中创建了一个嵌套的选项卡导航器,如下所示:

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

function TabNav () {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={HomeScreen}></Tab.Screen>
      <Tab.Screen name="Category" component={CategoryScreen}></Tab.Screen>
      <Tab.Screen name="Settings" component={SettingsScreen}></Tab.Screen>
    </Tab.Navigator>
  )
} 

export default function App() {
  return (
    <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen name="Tab" component={TabNav}></Stack.Screen>
          <Stack.Screen name="Category" component={CategoryScreen}>
          </Stack.Screen>
          <Stack.Screen
            name="SpecialBeerScreen" component= {SpecialBeerScreen}>
          </Stack.Screen>
        </Stack.Navigator>
    </NavigationContainer>
  )
}

但是,对于每个屏幕,标题现在看起来都类似于Tab。如何使用自定义文本(例如“首页”,“类别”等)为每个屏幕覆盖此标题。

enter image description here

2 个答案:

答案 0 :(得分:2)

如果我正确理解了您的问题,那么您想在更改选项卡时更改堆栈标题。在这种情况下,您可以使用React Context对其进行控制。

(我还将这段代码放在了小吃https://snack.expo.io/@gie3d/change-header-from-tab中)

编辑:1,我将其分成3个文件,并假定它们都在同一目录中。

HomeTitleContext.js

export const HomeTitleContext = React.createContext({
    title: 'default title',
    setTitle: () => {},
});

App.js

import { HomeTitleContext } from './HomeTitleContext';

export default function App() {
    const [title, setTitle] = useState('default title');
    return (
        <HomeTitleContext.Provider
            value={{
                title,
                setTitle,
            }}
        >
            <HomeTitleContext.Consumer>
                {(ctx) => (
                    <NavigationContainer>
                        <Stack.Navigator>
                            <Stack.Screen
                                name="Tab"
                                component={TabNav}
                                options={{ title: ctx.title }} // The title will be dynamically changed here
                            />
                            <Stack.Screen
                                name="Category"
                                component={OtherScreen}
                            ></Stack.Screen>
                            <Stack.Screen
                                name="SpecialBeerScreen"
                                component={OtherScreen}
                            ></Stack.Screen>
                        </Stack.Navigator>
                    </NavigationContainer>
                )}
            </HomeTitleContext.Consumer>
        </HomeTitleContext.Provider>
    );
}

在您的组件中,例如:HomeScreen,您设置了useFocusEffect并更改了setTitle的标题,您将从上下文中获取

HomeScreen.js

import React, { useContext } from 'react';
import { useFocusEffect } from '@react-navigation/native';
import { View, Text } from 'react-native';

import { HomeTitleContext } from './HomeTitleContext';

const HomeScreen = ({ navigation }) => {
    const { setTitle } = useContext(HomeTitleContext);
    useFocusEffect(() => {
        setTitle('this is home');
    });

    return (
        <View>
            <Text>Home</Text>
        </View>
    );
};

答案 1 :(得分:1)

使用GroupBy.sum部分中的react-navigation文档中概述的getFocusedRouteNameFromRoute来访问嵌套导航器中的屏幕信息。

更改此行

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

添加到以下内容(添加options道具):

<Stack.Screen
  name="Tab"
  component={TabNav}
  options={({ route }) => {
    const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';

    switch (routeName) {
      case 'Category': {
        return {
          headerTitle: 'Category',
        };
      }
      case 'Settings': {
        return {
          headerTitle: 'Settings',
        };
      }
      case 'Home':
      default: {
        return {
          headerTitle: 'Home',
        };
      }
    }
  }}
/>

您还必须导入getFocusedRouteNameFromRoute,所以还要添加:

import { getFocusedRouteNameFromRoute } from '@react-navigation/native';