【问题标题】:React native drawer navigator not opening反应本机抽屉导航器未打开
【发布时间】:2022-02-04 16:55:30
【问题描述】:

我正在构建一个反应原生应用程序并使用反应导航 v6 库。我已经构建了一个反应导航器,它在大多数情况下都可以正常工作,但是在导航到某个页面时我遇到了这个错误。

我有一个堆栈导航器:

   <NavigationContainer>

      <Stack.Navigator >
        <Stack.Screen name='LandingScreen' component={LandingScreen} options={{headerShown: false}} />
        <Stack.Screen name='LoginScreen' component={LoginScreen} options={{headerShown: false}} />
        <Stack.Screen name='RegisterScreen' component={RegisterScreen} options={{headerShown: false}} />

        <Stack.Screen name='CocktailDetailScreen' component={CocktailDetailScreen} options={{ header: () => <Header/> }} />

        <Stack.Screen name='HomeScreen' component={DrawerNavigator} options={{ header: () => <Header/> }} />
      </Stack.Navigator>
    </NavigationContainer>

还有抽屉导航器:

    <Drawer.Navigator screenOptions={{
        drawerStyle: {
          backgroundColor: 'white',
          zIndex: 100
        },
        drawerPosition: 'right'
      }}>
        <Drawer.Screen name='Search cocktails' component={HomeScreen} options={{headerShown: false}} />
        <Drawer.Screen name='Profile' component={ProfileScreen} options={{headerShown: false}} />
        <Drawer.Screen name='Publish a recipe' component={PublishRecipeScreen} options={{headerShown: false}} />

        <Drawer.Screen name='Favorites' component={FavoritesScreen} options={{headerShown: false}} />
        <Drawer.Screen name='Published recipes' component={PublishedRecipesScreen} options={{headerShown: false}} />
        <Drawer.Screen name='Log out' component={LandingScreen} options={{headerShown: false}} />
    </Drawer.Navigator>

导航到 CocktailDetailScreen 时出现问题,问题是抽屉无法打开。抽屉从标题组件(由 CocktailDetailScreen、homeScreen 和抽屉内的所有屏幕共享)打开,我使用navigation.dispatch(DrawerActions.toggleDrawer()) 打开它。这在除此屏幕之外的所有屏幕上都可以正常工作。

我认为如果我从堆栈导航器中删除 CocktailDetailScreen 并将其添加到抽屉导航器中,那么抽屉将正常打开。但我不希望这样,因为该页面只能通过其他屏幕访问,而不是直接从“菜单”/导航器访问。

我确信这是可能的,但我不明白我做错了什么。也许我没有正确嵌套导航器或者屏幕根本不应该在导航器中?

完整代码在这里:https://github.com/coccagerman/mixr

【问题讨论】:

    标签: javascript react-native react-navigation react-navigation-drawer react-navigation-v6


    【解决方案1】:

    抽屉导航器嵌套在堆栈导航器中,下面的屏幕可以访问抽屉特定的操作(打开、关闭或切换)

    • 搜索鸡尾酒
    • 简介
    • 发布食谱
    • 收藏夹
    • 已发布的食谱
    • 注销

    因为它们是抽屉导航器的子级。

    要使所有屏幕都可以访问 Drawer 操作,Drawer 必须是所有导航器的父级。

    让我们重构我们的代码如下。

    
    const PublicStack = (
      <Stack.Navigator>
        <Stack.Screen
          name="LandingScreen"
          component={LandingScreen}
          options={{ headerShown: false }}
        />
        <Stack.Screen
          name="LoginScreen"
          component={LoginScreen}
          options={{ headerShown: false }}
        />
        <Stack.Screen
          name="RegisterScreen"
          component={RegisterScreen}
          options={{ headerShown: false }}
        />
    
        <Stack.Screen
          name="CocktailDetailScreen"
          component={CocktailDetailScreen}
          options={{ header: () => <Header /> }}
        />
    
        <Stack.Screen
          name="HomeScreen"
          component={DrawerNavigator}
          options={{ header: () => <Header /> }}
        />
      </Stack.Navigator>
    );
    
    const ProtectedStack = () => (
      <Stack.Navigator>
        <Stack.Screen
          name="Search cocktails"
          component={HomeScreen}
          options={{ headerShown: false }}
        />
        <Stack.Screen
          name="Profile"
          component={ProfileScreen}
          options={{ headerShown: false }}
        />
        <Stack.Screen
          name="Publish a recipe"
          component={PublishRecipeScreen}
          options={{ headerShown: false }}
        />
    
        <Stack.Screen
          name="Favorites"
          component={FavoritesScreen}
          options={{ headerShown: false }}
        />
        <Stack.Screen
          name="Published recipes"
          component={PublishedRecipesScreen}
          options={{ headerShown: false }}
        />
        <Stack.Screen
          name="Log out"
          component={LandingScreen}
          options={{ headerShown: false }}
        />
      </Stack.Navigator>
    );
    
    const MainStack = () => {
      // Mocked logic for authentication, Implement actually logic
      const isLoggedIn = true;
    
      return (
        <NavigationContainer>
          <Drawer.Navigator
            screenOptions={{
              drawerStyle: {
                backgroundColor: "white",
                zIndex: 100,
              },
              drawerPosition: "right",
            }}
          >
            {isLoggedIn ? (
              <Drawer.Screen
                name="ProtectedStack"
                component={ProtectedStack}
                options={{ header: () => <Header /> }}
              />
            ) : (
              <Drawer.Screen
                name="PublicStack"
                component={PublicStack}
                options={{ header: () => <Header /> }}
              />
            )}
    
            {/* This screen can be accessible even if when user is not authenticated */}
    
            <Drawer.Screen
              name="CocktailDetailScreen"
              component={CocktailDetailScreen}
              options={{ header: () => <Header /> }}
            />
          </Drawer.Navigator>
        </NavigationContainer>
      );
    };
    
    
    

    这是您的要求的参考、重构和结构导航。

    通过https://reactnavigation.org/docs/nesting-navigators/#navigator-specific-methods-are-available-in-the-navigators-nested-inside了解更多信息

    【讨论】:

    • 谢谢你!非常有帮助。关键是要访问导航器操作,例如打开/关闭抽屉,屏幕必须是该导航器的子项。我将把我的实现留给文档。如果您不介意,我还有一个简短的问题,在 Drawer.Navigator 中放置 Stack.Screens 有什么用?拥有不同类型的导航器屏幕没有关系吗?干杯!
    • 忽略,是打字错误
    【解决方案2】:

    我的实现如下:

    import { NavigationContainer } from '@react-navigation/native'
    import { createNativeStackNavigator } from '@react-navigation/native-stack'
    import { createDrawerNavigator } from '@react-navigation/drawer'
    
    import * as React from 'react'
    
    import LandingScreen from '../screens/LandingScreen'
    import LoginScreen from '../screens/LoginScreen'
    import RegisterScreen from '../screens/RegisterScreen'
    import HomeScreen from '../screens/HomeScreen'
    import ProfileScreen from '../screens/ProfileScreen'
    import CocktailDetailScreen from '../screens/CocktailDetailScreen'
    import PublishRecipeScreen from '../screens/PublishRecipeScreen'
    import FavoritesScreen from '../screens/FavoritesScreen'
    import PublishedRecipesScreen from '../screens/PublishedRecipesScreen'
    
    import Header from '../components/Header'
    
    import { RootStackParamList } from '../types'
    
    export default function Navigation() {
    
      const Stack = createNativeStackNavigator<RootStackParamList>()
      const Drawer = createDrawerNavigator()
    
      const isLoggedIn = false
    
      const loginStack = () => (
        <Stack.Navigator >
          <Stack.Screen name='LandingScreen' component={LandingScreen} options={{headerShown: false}} />
          <Stack.Screen name='LoginScreen' component={LoginScreen} options={{headerShown: false}} />
          <Stack.Screen name='RegisterScreen' component={RegisterScreen} options={{headerShown: false}} />
        </Stack.Navigator>
      )
    
      return (
        <NavigationContainer>
          <Drawer.Navigator screenOptions={{
            drawerStyle: { backgroundColor: 'white' },
            drawerPosition: 'right'
          }}>
    
            {!isLoggedIn ? (
              <Stack.Screen
                name="PublicStack"
                component={loginStack}
                options={{headerShown: false}}
              /> )
            :
            (<>
              <Drawer.Screen name='Search cocktails' component={HomeScreen} options={{ header: () => <Header/> }} />
              <Drawer.Screen name='Profile' component={ProfileScreen} options={{ header: () => <Header/> }} />
              <Drawer.Screen name='Publish a recipe' component={PublishRecipeScreen} options={{ header: () => <Header/> }} />
              <Drawer.Screen name='Favorites' component={FavoritesScreen} options={{ header: () => <Header/> }} />
              <Drawer.Screen name='Published recipes' component={PublishedRecipesScreen} options={{ header: () => <Header/> }} />
              <Drawer.Screen name='Log out' component={LandingScreen} options={{ header: () => <Header/> }} />
    
              <Drawer.Screen name='CocktailDetailScreen' component={CocktailDetailScreen} options={{
                header: () => <Header/>,
                drawerLabel: () => null,
                title: undefined
              }} />
            </>
            )}
    
          </Drawer.Navigator>
        </NavigationContainer>
      )
    }
    

    我将抽屉导航器设为主导航器,并为登陆、注册和登录页面创建了一个不同的堆栈导航器。

    在抽屉中,我将这个单独的堆栈导航器作为子屏幕并将堆栈导航器作为组件传递给它。

    抽屉屏幕和我之前的一样,除了现在 CocktailDetailScreen 也是抽屉导航器的孩子,多亏了它,我现在可以对其进行操作。由于我不希望通过导航器菜单访问该屏幕,因此我只是不使用 drawerLabel: () =&gt; null, title: undefined

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      • 1970-01-01
      • 1970-01-01
      • 2019-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多