React Native右侧抽屉导航无法正常使用问题求助
问题解决:React Native 左右抽屉导航分别触发
问题根源
- 嵌套抽屉导航时,组件通过
useNavigation()默认获取的是最近层级的抽屉导航实例,所以右侧头像点击时调用的是内层左侧抽屉的openDrawer(),而非外层右侧抽屉。 drawerPosition配置位置错误,应该设置在Drawer.Navigator的参数中,而非单个Screen的options里。
修改方案
- 给外层右侧抽屉导航器设置唯一ID,用于指定触发目标
- 使用
DrawerActions.openDrawer并传入target参数,精准触发对应抽屉 - 修正
drawerPosition的配置位置 - 为所有页面的右侧头像添加统一的点击逻辑
修改后的完整代码
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
相关产品推荐
相关产品推荐

