簡體   English   中英

反應本機抽屜導航器未打開

[英]React native drawer navigator not opening

我正在構建一個反應原生應用程序並使用反應導航 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 時會出現問題,問題是抽屜無法打開。 抽屜從 header 組件(由 CocktailDetailScreen、homeScreen 和抽屜內的所有屏幕共享)打開,我使用navigation.dispatch(DrawerActions.toggleDrawer())打開它。 這在除此之外的每個屏幕上都可以正常工作。

我想如果我從堆棧導航器中刪除 CocktailDetailScreen 並將其添加到抽屜導航器中,那么抽屜會正常打開。 但我不希望這樣,因為這個頁面只能通過其他屏幕訪問,而不是直接從“菜單”/導航器訪問。

我確信這是可能的,但我不明白我做錯了什么。 也許我沒有正確嵌套導航器,或者屏幕根本不應該在導航器中?

完整代碼在這里: https://github.com/coccagerman/mixr

抽屜導航器嵌套在堆棧導航器內,下面的屏幕可以訪問抽屜特定的操作(打開、關閉或切換)

  • 搜索雞尾酒
  • 輪廓
  • 發布食譜
  • 收藏夾
  • 已發表的食譜
  • 登出

因為他們是抽屜導航器的孩子。

要使所有屏幕都可以訪問 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 ? (
          <Stack.Screen
            name="ProtectedStack"
            component={ProtectedStack}
            options={{ header: () => <Header /> }}
          />
        ) : (
          <Stack.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探索更多信息

我的實現如下:

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: () => null, title: undefined

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM