React Navigation 6跨导航器跳转报错:Payload未被任何导航器处理
问题背景
升级到React Navigation 6后,尝试从抽屉导航(DrawerNavigator)的CaseloadScreen页面跳转到包含底部标签导航(BottomTabNavigator)的PatientScreen页面时,点击按钮触发如下错误:
The action 'NAVIGATE' with payload undefined was not handled by any navigator.
Do you have a screen named 'PatientScreen'?
错误原因
PatientScreen未在抽屉导航的屏幕列表中注册,导致导航器无法识别目标页面- 跨嵌套导航器的跳转写法不符合React Navigation 6的规范
解决方案
步骤1:在抽屉导航中注册PatientScreen
首先在DrawerNavigation组件中导入PatientScreen,并将其添加到抽屉导航的屏幕列表中:
修改后的抽屉导航代码:
import React from 'react'; import { StyleSheet, View, Text, Button } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createDrawerNavigator, DrawerContentScrollView, DrawerItemList, DrawerItem, } from '@react-navigation/drawer'; import { LoginScreen } from '../screens/LoginScreen'; import { CaseloadScreen } from '../screens/CaseloadScreen'; import { WeeklyScreen } from '../screens/WeeklyScreen'; import { ProfileScreen } from '../screens/ProfileScreen'; // 新增导入PatientScreen import { PatientScreen } from '../screens/PatientScreen'; import { Ionicons, FontAwesome, MaterialCommunityIcons, AntDesign } from '@expo/vector-icons'; import { AvailablePatientScreen } from '../screens/AvailablePatientScreen'; const CustomDrawerContent = (props) => { return ( <DrawerContentScrollView {...props}> <DrawerItemList {...props} style={{ activeTintColor: { color: '#fff', }, }} /> </DrawerContentScrollView> ); } const Drawer = createDrawerNavigator(); const DrawerNavigation = () => { const icons = { tintColor: '#fff', size: 20, } return ( <Drawer.Navigator initialRouteName={'Caseload'} drawerContent={(props) => <CustomDrawerContent {...props} />} screenOptions={{ labelStyle: { color: '#fff', }, inactiveTintColor: { color: '#fff', }, drawerStyle: { backgroundColor: 'rgb(61,77,138)', width: 240, activeTintColor: 'rgb(61,77,138)', activeBackgroundColor: '#fff', inactiveTintColor: '#fff', inactiveBackgroundColor: 'rgb(61,77,138)', }, }} > <Drawer.Screen name="Caseload" component={CaseloadScreen} options={{ drawerIcon: () => (<Ionicons name="ios-home" size={icons.size} color={icons.tintColor} />) }} /> <Drawer.Screen name="Weekly Summary" component={WeeklyScreen} options={{ drawerIcon: () => (<FontAwesome name="bar-chart" size={icons.size} color={icons.tintColor} />) }} /> <Drawer.Screen name="Available RiverKids" component={AvailablePatientScreen} options={{ drawerIcon: () => (<FontAwesome name="child" size={icons.size} color={icons.tintColor} />) }} /> <Drawer.Screen name="My Profile" component={ProfileScreen} options={{ drawerIcon: () => (<AntDesign name="profile" size={icons.size} color={icons.tintColor} />) }} /> // 取消注释并注册PatientScreen <Drawer.Screen name="Patient" component={PatientScreen} options={{ drawerIcon: () => (<FontAwesome name="bar-chart" size={icons.size} color={icons.tintColor} />) }} /> <Drawer.Screen name="Login" component={LoginScreen} options={{ title: 'Sign Out', drawerIcon: () => (<MaterialCommunityIcons name="logout" size={icons.size} color={icons.tintColor} />) }} /> </Drawer.Navigator> ); } export const Navigator = () => { return ( <NavigationContainer> <DrawerNavigation /> </NavigationContainer> ); }
步骤2:调整CaseloadScreen中的跳转代码
由于PatientScreen是嵌套的底部标签导航器,跳转时需要匹配抽屉导航中注册的屏幕名称(Patient);如果需要直接跳转到PatientScreen内的Visits标签,可使用嵌套跳转写法:
修改后的CaseloadScreen代码:
import { StyleSheet, Text, View, Button } from 'react-native'; export const CaseloadScreen = ({navigation}) => { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Caseload</Text> <Button title="Patient" // 跳转到抽屉导航中的Patient屏幕,并指定默认显示Visits标签 onPress={() => navigation.navigate('Patient', { screen: 'Visits' })} /> </View> ); }
关键说明
- React Navigation中,所有需要通过
navigation.navigate访问的屏幕必须在对应导航器中注册 - 嵌套导航器的跳转需遵循父导航器屏幕名称 -> 子导航器屏幕名称的层级结构,通过
screen参数指定子导航器的目标页面
内容的提问来源于stack exchange,提问作者Muirik
相关产品推荐
相关产品推荐

