【问题标题】:Can't call a nested navigation screen from a deep component in react native无法从反应原生的深层组件调用嵌套导航屏幕
【发布时间】:2021-09-18 10:25:13
【问题描述】:

我已关注 this tutorial 并为我的 react native expo 应用程序创建了抽屉和主选项卡导航。

现在我需要一个不应在 Drawer 或 Tab 中列出的屏幕,并且需要从不发送导航道具的深层组件中调用它。

我尝试了 useNavigation Hook,但在 react native 无法找到任何此类屏幕名称时出现错误。

PFB 暂定示例代码: 从 App.js 调用的主选项卡

const Tab = createMaterialBottomTabNavigator();
const HomeStack = createStackNavigator();
const ProfileStack = createStackNavigator();
const ListStack = createStackNavigator();

const MainTabScreen = () => (
    <Tab.Navigator
      initialRouteName="Home"
      activeColor="#fff"
      barStyle={{ backgroundColor: '#009387' }}
    >
      <Tab.Screen
        name="Home"
        component={HomeStackScreen}
        options={{
          tabBarLabel: 'Home',
          tabBarColor: '#009387',
          tabBarIcon: ({ color }) => (
            <Icon name="home" color={color} size={26} />
          ),
        }}
      />
      <Tab.Screen
        name="Profile"
        component={ProfileStackScreen}
        options={{
          tabBarLabel: 'Profile',
          tabBarColor: '#1f65ff',
          tabBarIcon: ({ color }) => (
            <Icon name="aperture" color={color} size={26} />
          ),
        }}
      />
</Tab.Navigator>
);

export default MainTabScreen;

const HomeStackScreen = ({navigation}) => (
  <HomeStack.Navigator screenOptions={{
    headerStyle: {
      backgroundColor: '#009387',
    },
    headerTintColor: '#fff',
    headerTitleStyle: {
      fontWeight: 'bold'
    }
  }}>
    <HomeStack.Screen name = "Home" component = {Home}
    options = {{
      title: 'Overview',
      headerLeft: () => (
        <Icon.Button name="menu" size={25}
        backgroundColor="#009387" onPress={()=>navigation.openDrawer()} 
        ></Icon.Button>
        )
    }}
    />
  </HomeStack.Navigator>
);

const ProfileStackScreen = ({navigation}) => (
  <ProfileStack.Navigator screenOptions={{
    headerStyle: {
      backgroundColor: '#d02860',
    },
    headerTintColor: '#fff',
    headerTitleStyle: {
      fontWeight: 'bold'
    }
  }}>
    <ProfileStack.Screen name = "Profile" component = {Profile}
    options = {{
      headerLeft: () => (
        <Icon.Button name="menu" size={25}
        backgroundColor="#d02860" onPress={()=>navigation.openDrawer()} 
        ></Icon.Button>
        )
    }}
    />
  </ProfileStack.Navigator>
);

const ListStackScreen = ({navigation}) => (
  <NotificationsStack.Navigator screenOptions={{
    headerStyle: {
      backgroundColor: '#694fad',
    },
    headerTintColor: '#fff',
    headerTitleStyle: {
      fontWeight: 'bold'
    }
  }}>
    <ListStack.Screen name = "List" component = {List}
    options = {{
      headerLeft: () => (
        <Icon.Button name="menu" size={25}
        backgroundColor="#694fad" onPress={()=>navigation.openDrawer()} 
        ></Icon.Button>
        )
    }}
    />
  </NotificationsStack.Navigator>
);

useNavigation 组件部分:

import { useNavigation } from '@react-navigation/native';
.
.
.
const SomeStuff = ({item}) => {
......
<ListButton title={Count} screenName="ListStackScreen" />
.....
}
.
.

function ListButton({ title, screenName }) {
  const navigation = useNavigation();

  return (
    <Button
      title={`${title} Total`}
      onPress={() => navigation.navigate(screenName)}
    />
  );
}

也试过了:

navigation.navigate('HomeDrawer',{screen: screenName})

我需要从深层组件调用上面的 ListStackScreen。我尝试使用 navigation.navigate(ListStackScreen) 但它不像上面解释的那样工作。 请让我知道如何使用屏幕而不在任何抽屉或标签中直观地显示它。

编辑:尝试给定答案后更新 我在主 app.js 中也有这个:

<Drawer.Screen name="HomeDrawer" component={MainTabScreen} />

【问题讨论】:

  • 您能展示一下您是如何尝试实现 useNavigation 的吗?
  • @MichaelBahl 我在问题中更新了相同的内容。请检查。
  • 您也没有将 ListStackScreen 添加到选项卡屏幕或 Stacknavigator。
  • @MichaelBahl 没有添加到选项卡屏幕,因为我不想在选项卡抽屉菜单上显示它。我不需要将它包含在菜单中,但仍然能够从任何其他深层组件导航该屏幕

标签: react-native react-navigation


【解决方案1】:

此设置应允许您在 HomeStackScreen 和 ListStackScreen 之间导航。

const Stack = createStackNavigator();

function HomeStack() {
  return (
    <Stack.Navigator
      initialRouteName="HomeStackScreen">
      <Stack.Screen
        name="HomeStackScreen"
        component={HomeStackScreen}
      />
      <Stack.Screen
        name="ListStackScreen"
        component={ListStackScreen}
      />
    </Stack.Navigator>
  );
}

    <NavigationContainer>
      <Tab.Navigator
        initialRouteName="HomeStack">
        <Tab.Screen
          name="HomeStack"
          component={HomeStack}
          }}
        />
    …

您可以将stacknavigator嵌套到Drawer中,内部stacknavigator屏幕不会显示在Drawer中。

我创建了一个sample

【讨论】:

  • 感谢您的回复。试过了,现在我在问题中更新了 2 个菜单栏。我确实在 app.js 中有主抽屉,在选项卡屏幕中有剩余的东西。由于我是新手,因此请告诉我是否有任何方法可以在 部分中使用它...
  • 正如您在我的示例中看到的那样,我禁用了第二个导航栏 headerShown: false
  • @MicaelBahl 谢谢。它现在正在工作。已将此标记为答案。我还面临一个小故障。一旦我从深层组件转到 ListStackScreen,然后转到不同的选项卡菜单,然后按主选项卡菜单,则 ListStackScreen 仍然显示在此处。我必须单击 Home 菜单选项卡两次才能加载 HomeStackScreen。非常感谢任何进一步的指导......
  • 这是我认为你不应该覆盖它的默认行为。不过,您可以设置 Tab.Screen->options->unmountOnBlur->true 来覆盖此行为并将 StackNavigator 设置为初始屏幕。
  • @MichaleBahl 这个 OnBlur 东西不起作用......但是想保持它的默认行为方式......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多