首页 > 解决方案 > React 导航抽屉 V5

问题描述

我正在使用 react-navigation 版本 5。我有标签导航和抽屉导航。

我正在尝试在标题中添加一个图标来打开/关闭抽屉:

这是我用于切换抽屉的自定义右标题:

const HeaderRight = ({ navigation }) => {   
    return (
      <View style={{flexDirection: 'row'}}>
        <TouchableOpacity
        onPress={ () =>{ navigation.toggleDrawer()}}>  //here is the problem
          <Image source={require('./assets/images/icons/drawer.png')}/>
        </TouchableOpacity>
      </View>
    );}

这是我的标签导航器:

const Tab = createBottomTabNavigator();
function AppTab() {
  return (
     <Tab.Navigator>         
        <Tab.Screen name="Category" component={Category} />    
        <Tab.Screen name="Home" component={Home}/>
      </Tab.Navigator>
   );}

抽屉导航器:

    const Drawer = createDrawerNavigator();  
    function App() {
      return (    
          <Drawer.Navigator>
            <Drawer.Screen name="AppTab" component={AppTab} />
            <Drawer.Screen name="Notifications" component={NotificationsScreen} />
          </Drawer.Navigator>  
      );}

和我的堆栈导航器主题混合:

const Stack = createStackNavigator();
  export default function MyStack() {
  return (
    <NavigationContainer>
    <Stack.Navigator
    headerMode="screen"
     screenOptions={{
          headerRight: ({ navigation }) => (<HeaderRight navigation={navigation} />
        ),}} >
      <Stack.Screen name="Settings" component={Settings} />
    </Stack.Navigator>
    </NavigationContainer>
  );
}

当我按下右标题图标时在此处输入图像描述

我在这里缺少什么?这些文件并没有真正的帮助

注意:我也尝试过使用 dispatch 但它不起作用:

navigation.dispatch(DrawerActions.toggleDrawer())

包.json:

{
  "name": "test",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "@react-native-community/async-storage": "^1.8.0",
    "@react-native-community/masked-view": "^0.1.6",
    "@react-navigation/bottom-tabs": "^5.0.5",
    "@react-navigation/drawer": "^5.0.5",
    "@react-navigation/native": "^5.0.5",
    "@react-navigation/stack": "^5.0.5",
    "moment": "^2.24.0",
    "randomcolor": "^0.5.4",
    "react": "16.9.0",
    "react-native": "0.61.5",
    "react-native-base64": "0.0.2",
    "react-native-gesture-handler": "^1.6.0",
    "react-native-image-slider": "^2.0.3",
    "react-native-reanimated": "^1.7.0",
    "react-native-safe-area-context": "^0.7.3",
    "react-native-screens": "^2.0.0-beta.4",
    "react-native-woocommerce-api": "^1.0.12"
  },
  "devDependencies": {
    "@babel/core": "^7.6.2",
    "@babel/runtime": "^7.6.2",
    "@react-native-community/eslint-config": "^0.0.5",
    "babel-jest": "^24.9.0",
    "eslint": "^6.5.1",
    "jest": "^24.9.0",
    "metro-react-native-babel-preset": "^0.56.0",
    "react-test-renderer": "16.9.0"
  },
  "jest": {
    "preset": "react-native"
  }
}

标签: react-nativereact-navigationreact-native-navigationreact-navigation-v5

解决方案


我根据我的理解创建了一个简单的示例,希望对您有所帮助,

您可以使用 Stack.Screen 的 options 道具来呈现自定义的左右按钮,并在按钮组件中使用 useNavigation 挂钩来获取导航道具并切换抽屉用户navigation.dispatch(DrawerActions.toggleDrawer())

import React, {useEffect} from 'react';
import {View, Text, StyleSheet, Image} from 'react-native';
import {NavigationContainer, useNavigation, DrawerActions} from '@react-navigation/native';
import {createDrawerNavigator} from '@react-navigation/drawer';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {createStackNavigator, HeaderBackButton, Header} from '@react-navigation/stack';
import Home from './src/home';
import {TouchableOpacity} from 'react-native-gesture-handler';

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

const TabComponent = () => {
  return (
    <Tab.Navigator>
      <Tab.Screen component={Home} name="Home1" />
      <Tab.Screen component={Home} name="Home2" />
      {/*
       * Rest Screens
       */}
    </Tab.Navigator>
  );
};

const DrawerComponent = () => {
  return (
    <Drawer.Navigator>
      <Drawer.Screen component={TabComponent} name="Main" />
      {/*
       * Rest Screens
       */}
    </Drawer.Navigator>
  );
};

const HeaderLeft = () => {
  const navigation = useNavigation();
  return (
    <View style={{flexDirection: 'row'}}>
      <TouchableOpacity
        onPress={() => {
          navigation.dispatch(DrawerActions.openDrawer());
        }}>
        <Text>Open</Text>
        {/* <Image source={require('./assets/images/icons/drawer.png')} /> */}
      </TouchableOpacity>
    </View>
  );
};

export default () => {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          options={{
            headerLeft: ({}) => <HeaderLeft />
          }}
          component={DrawerComponent}
          name="Drawer"
        />
        {/*
         * Rest Screens
         */}
      </Stack.Navigator>
    </NavigationContainer>
  );
};

推荐阅读