You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native右侧抽屉导航无法正常使用问题求助

问题解决:React Native 左右抽屉导航分别触发

问题根源

  1. 嵌套抽屉导航时,组件通过useNavigation()默认获取的是最近层级的抽屉导航实例,所以右侧头像点击时调用的是内层左侧抽屉的openDrawer(),而非外层右侧抽屉。
  2. drawerPosition配置位置错误,应该设置在Drawer.Navigator的参数中,而非单个Screen的options里。

修改方案

  1. 给外层右侧抽屉导航器设置唯一ID,用于指定触发目标
  2. 使用DrawerActions.openDrawer并传入target参数,精准触发对应抽屉
  3. 修正drawerPosition的配置位置
  4. 为所有页面的右侧头像添加统一的点击逻辑

修改后的完整代码

import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import React from 'react';
import { createDrawerNavigator, DrawerActions } from '@react-navigation/drawer';
import { useNavigation } from '@react-navigation/native';

import SignUpScreen from './SignUpScreen';
import SignInScreen from './SignInScreen';
import Watchlist from './Watchlist';
import AlgoTrader from './AlgoTrader';
import Portfolio from './Portfolio';
import Insights from './Insights';
import Home from './Home';
import Welcome from './Welcome';

import Hamburger from "../Assets/Hamburger";
import ProfilePhoto from "../Assets/ProfilePhoto";
import HomeActive from '../Assets/HomeActive';
import HomeInactive from '../Assets/HomeInactive';
import WatchlistActive from '../Assets/WatchlistActive';
import WatchlistInactive from '../Assets/WatchlistInactive';
import AlgoTraderActive from '../Assets/AlgoTraderActive';
import AlgoTraderInactive from '../Assets/AlgoTraderInactive';
import PortfolioActive from '../Assets/PortfolioActive';
import PortfolioInactive from '../Assets/PortfolioInactive';
import InsightsActive from '../Assets/InsightsActive';
import InsightsInactive from '../Assets/InsightsInactive';

const insightsData = "NIFTY";
const Tab = createBottomTabNavigator();
const Drawer = createDrawerNavigator();
const ProfileDrawer = createDrawerNavigator();

const CustomDrawerContent = () => {
  return (
    <View>
      <Text>Left drawer</Text>
    </View>
  );
};

const CustomRightDrawerContent = () => {
  return (
    <View>
      <Text>Right Drawer</Text>
    </View>
  );
};

const ProfileTabNavigator = () => {
  const navigation = useNavigation();

  // 打开右侧抽屉的方法
  const openRightDrawer = () => {
    navigation.dispatch(DrawerActions.openDrawer({ target: 'rightDrawer' }));
  };

  return (
    <Tab.Navigator>
      <Tab.Screen
        name="Home"
        component={Home}
        initialParams={{ title: "Home1", customProp: insightsData }}
        options={{
          headerShown: true,
          title: "Home",
          headerTintColor: "#0B588D",
          headerTitleAlign: 'center',
          headerTitleStyle: {
            fontWeight: "600",
          },
          headerLeft: () => (
            <TouchableOpacity style={{ marginTop: 10 }} onPress={() => navigation.openDrawer()}>
              <Hamburger height="30" width="30" onPress={() => navigation.openDrawer()} />
            </TouchableOpacity>
          ),
          headerRight: () => (
            <TouchableOpacity style={{ marginTop: 10 }} onPress={openRightDrawer}>
              <ProfilePhoto height="30" width="30" />
            </TouchableOpacity>
          ),
          tabBarLabel: ({ focused, color }) => (
            <Text style={{ textDecorationLine: focused ? 'underline' : 'none', color: focused ? '#0B588D' : 'gray' }}>Home</Text>
          ),
          tabBarIcon: ({ color, size, focused }) => (
            focused ? <HomeActive width={25} height={25} /> : <HomeInactive width={25} height={25} />
          ),
        }}
      />

      <Tab.Screen
        name="Watchlist"
        component={Watchlist}
        options={{
          headerShown: true,
          title: "FTSM Watchlist",
          headerTintColor: "#0B588D",
          headerTitleAlign: 'center',
          headerTitleStyle: {
            fontWeight: "600",
          },
          headerRight: () => (
            <TouchableOpacity style={{ marginTop: 10 }} onPress={openRightDrawer}>
              <ProfilePhoto height="30" width="30" />
            </TouchableOpacity>
          ),
          headerLeft: () => (
            <TouchableOpacity style={{ marginTop: 10 }} onPress={() => navigation.openDrawer()}>
              <Hamburger height="30" width="30" />
            </TouchableOpacity>
          ),
          tabBarLabel: ({ focused, color }) => (
            <Text style={{ textDecorationLine: focused ? 'underline' : 'none', color: focused ? '#0B588D' : 'gray' }}>Watchlist</Text>
          ),
          tabBarIcon: ({ color, size, focused }) => (
            focused ? <WatchlistActive width={25} height={25} /> : <WatchlistInactive width={25} height={25} />
          ),
        }}
      />

      <Tab.Screen
        name="Algo Trader"
        component={AlgoTrader}
        options={{
          headerShown: true,
          title: "Algo Traders",
          headerTintColor: "#0B588D",
          headerTitleAlign: 'center',
          headerTitleStyle: {
            fontWeight: "600",
          },
          headerRight: () => (
            <TouchableOpacity style={{ marginTop: 10 }} onPress={openRightDrawer}>
              <ProfilePhoto height="30" width="30" />
            </TouchableOpacity>
          ),
          headerLeft: () => (
            <TouchableOpacity style={{ marginTop: 10 }} onPress={() => navigation.openDrawer()}>
              <Hamburger height="30" width="30" />
            </TouchableOpacity>
          ),
          tabBarLabel: ({ focused, color }) => (
            <Text style={{ textDecorationLine: focused ? 'underline' : 'none', color: focused ? '#0B588D' : 'gray' }}>Algo Trader</Text>
          ),
          tabBarIcon: ({ color, size, focused }) => (
            focused ? <AlgoTraderActive width={25} height={25} /> : <AlgoTraderInactive width={25} height={25} />
          ),
        }}
      />

      <Tab.Screen
        name="Portfolio"
        component={Portfolio}
        options={{
          headerShown: true,
          title: "My Portfolio",
          headerTintColor: "#0B588D",
          headerTitleAlign: 'center',
          headerTitleStyle: {
            fontWeight: "600",
          },
          headerRight: () => (
            <TouchableOpacity style={{ marginTop: 10 }} onPress={openRightDrawer}>
              <ProfilePhoto height="30" width="30" />
            </TouchableOpacity>
          ),
          headerLeft: () => (
            <TouchableOpacity style={{ marginTop: 10 }} onPress={() => navigation.openDrawer()}>
              <Hamburger height="30" width="30" />
            </TouchableOpacity>
          ),
          tabBarLabel: ({ focused, color }) => (
            <Text style={{ textDecorationLine: focused ? 'underline' : 'none', color: focused ? '#0B588D' : 'gray' }}>Portfolio</Text>
          ),
          tabBarIcon: ({ color, size, focused }) => (
            focused ? <PortfolioActive width={25} height={25} /> : <PortfolioInactive width={25} height={25} />
          ),
        }}
      />

      <Tab.Screen
        name="Insights"
        component={Insights}
        initialParams={{ data: insightsData }}
        options={{
          headerShown: true,
          title: "Insights",
          headerTintColor: "#0B588D",
          headerTitleAlign: 'center',
          headerTitleStyle: {
            fontWeight: "600",
          },
          headerRight: () => (
            <TouchableOpacity style={{ marginTop: 10 }} onPress={openRightDrawer}>
              <ProfilePhoto height="30" width="30" />
            </TouchableOpacity>
          ),
          headerLeft: () => (
            <TouchableOpacity style={{ marginTop: 10 }} onPress={() => navigation.openDrawer()}>
              <Hamburger height="30" width="30" />
            </TouchableOpacity>
          ),
          tabBarLabel: ({ focused, color }) => (
            <Text style={{ textDecorationLine: focused ? 'underline' : 'none', color: focused ? '#0B588D' : 'gray' }}>Insights</Text>
          ),
          tabBarIcon: ({ color, size, focused }) => (
            focused ? <InsightsActive width={25} height={25} /> : <InsightsInactive width={25} height={25} />
          ),
        }}
      />

    </Tab.Navigator>
  );
};

const ProfileDrawerNavigator = () => {
  return (
    // 将drawerPosition移到Navigator参数中
    <ProfileDrawer.Navigator 
      drawerContent={CustomDrawerContent}
      drawerPosition="left"
    >
      <ProfileDrawer.Screen name=" " component={ProfileTabNavigator} options={{ headerShown: false }} />
    </ProfileDrawer.Navigator>
  );
};

const Dashboard = () => {
  return (
    // 设置外层抽屉的id和drawerPosition
    <Drawer.Navigator 
      drawerContent={CustomRightDrawerContent}
      drawerPosition="right"
      id="rightDrawer"
    >
      <Drawer.Screen name=" " component={ProfileDrawerNavigator} options={{ headerShown: false }} />
    </Drawer.Navigator>
  );
};

export default Dashboard;

关键修改点说明

  • 外层抽屉导航器添加id="rightDrawer",用于指定触发目标
  • 在ProfileTabNavigator中定义openRightDrawer方法,通过navigation.dispatch发送带target的DrawerActions.openDrawer,精准触发外层右侧抽屉
  • 将drawerPosition从Screen的options移到Drawer.Navigator的参数中,配置生效
  • 给所有页面的headerRight按钮添加openRightDrawer点击事件
  • 关闭嵌套抽屉的重复header,避免界面冗余

内容的提问来源于stack exchange,提问作者abcd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 03:09:52