React Navigation报错:同一容器下多导航器冲突问题求助
大家好,我最近在做React Native项目的时候遇到了一个React Navigation的报错,试了好几种方法都没解决,特意来求助各位大神!
报错信息
Issue:
Another navigator is already registered for this container. You likely have multiple navigators under a single "NavigationContainer" or "Screen". Make sure each navigator is under a separate "Screen" container.
我的代码
我想要实现一个底部导航栏,其中Home和Profile标签页各自带有栈导航,可以跳转到详情页面,于是写了下面的代码:
import React, { useState } from 'react'; import { View, Text, Button } from 'react-native'; import { BottomNavigation } from 'react-native-paper'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; // Home Screens function HomeScreen({ navigation }) { return ( <View> <Text>Home Screen</Text> <Button title="Go to Details" onPress={() => navigation.navigate('Details')} /> </View> ); } function DetailScreen() { return ( <View> <Text>Detail Screen</Text> </View> ); } // Profile Screens function ProfileScreen({ navigation }) { return ( <View> <Text>Profile Screen</Text> <Button title="Go to Profile Details" onPress={() => navigation.navigate('ProfileDetails')} /> </View> ); } function ProfileDetailScreen() { return ( <View> <Text>Profile Detail Screen</Text> </View> ); } // Settings Screens function SettingsScreen() { return <Text>Settings Screen</Text>; } // Home Stack const HomeStack = createStackNavigator(); function HomeStackScreen() { return ( <HomeStack.Navigator> <HomeStack.Screen name="Home" component={HomeScreen} /> <HomeStack.Screen name="Details" component={DetailScreen} /> </HomeStack.Navigator> ); } // Profile Stack const ProfileStack = createStackNavigator(); function ProfileStackScreen() { return ( <ProfileStack.Navigator> <ProfileStack.Screen name="Profile" component={ProfileScreen} /> <ProfileStack.Screen name="ProfileDetails" component={ProfileDetailScreen} /> </ProfileStack.Navigator> ); } export default function App() { const [index, setIndex] = useState(0); // Tab index state const [routes] = useState([ { key: 'home', title: 'Home', icon: 'home' }, { key: 'profile', title: 'Profile', icon: 'account' }, { key: 'settings', title: 'Settings', icon: 'settings' }, ]); // Render scene based on selected tab const renderScene = BottomNavigation.SceneMap({ home: HomeStackScreen, // Home Stack for Home tab profile: ProfileStackScreen, // Profile Stack for Profile tab settings: SettingsScreen, // Single screen for Settings tab }); return ( // Wrap everything in a single NavigationContainer <NavigationContainer> <BottomNavigation navigationState={{ index, routes }} onIndexChange={setIndex} renderScene={renderScene} /> </NavigationContainer> ); }
问题分析
后来我仔细琢磨报错提示,才发现问题出在导航器的嵌套逻辑上:我用了react-native-paper的BottomNavigation来做底部导航,但它并不是React Navigation官方的导航器组件。直接把多个StackNavigator放在它里面,相当于在同一个NavigationContainer下注册了多个独立的导航器,这就违反了React Navigation的嵌套规则——每个子导航器必须放在父导航器的Screen容器下。
解决方案
正确的做法是使用React Navigation官方的createBottomTabNavigator作为根导航器,然后每个标签页对应的Screen组件里再嵌套StackNavigator,这样整个导航结构层级清晰,就不会出现多导航器冲突的问题了。
下面是修正后的完整代码:
import React from 'react'; import { View, Text, Button } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { Icon } from 'react-native-paper'; // Home Screens function HomeScreen({ navigation }) { return ( <View> <Text>Home Screen</Text> <Button title="Go to Details" onPress={() => navigation.navigate('Details')} /> </View> ); } function DetailScreen() { return ( <View> <Text>Detail Screen</Text> </View> ); } // Profile Screens function ProfileScreen({ navigation }) { return ( <View> <Text>Profile Screen</Text> <Button title="Go to Profile Details" onPress={() => navigation.navigate('ProfileDetails')} /> </View> ); } function ProfileDetailScreen() { return ( <View> <Text>Profile Detail Screen</Text> </View> ); } // Settings Screens function SettingsScreen() { return <Text>Settings Screen</Text>; } // Home Stack const HomeStack = createStackNavigator(); function HomeStackScreen() { return ( <HomeStack.Navigator> <HomeStack.Screen name="Home" component={HomeScreen} /> <HomeStack.Screen name="Details" component={DetailScreen} /> </HomeStack.Navigator> ); } // Profile Stack const ProfileStack = createStackNavigator(); function ProfileStackScreen() { return ( <ProfileStack.Navigator> <ProfileStack.Screen name="Profile" component={ProfileScreen} /> <ProfileStack.Screen name="ProfileDetails" component={ProfileDetailScreen} /> </ProfileStack.Navigator> ); } // 底部标签导航器 const Tab = createBottomTabNavigator(); export default function App() { return ( <NavigationContainer> <Tab.Navigator screenOptions={({ route }) => ({ // 使用react-native-paper的图标保持原视觉效果 tabBarIcon: ({ focused, color, size }) => { let iconName; switch(route.name) { case 'Home': iconName = 'home'; break; case 'Profile': iconName = 'account'; break; case 'Settings': iconName = 'settings'; break; default: iconName = 'home'; } return <Icon name={iconName} size={size} color={color} />; }, })} tabBarOptions={{ activeTintColor: '#2196F3', inactiveTintColor: 'gray', }} > <Tab.Screen name="Home" component={HomeStackScreen} /> <Tab.Screen name="Profile" component={ProfileStackScreen} /> <Tab.Screen name="Settings" component={SettingsScreen} /> </Tab.Navigator> </NavigationContainer> ); }
修正要点说明
- 替换了react-native-paper的
BottomNavigation为React Navigation官方的createBottomTabNavigator,让它作为根导航器统一管理所有标签页的导航逻辑 - 每个标签页的
Tab.Screen组件内部嵌套对应的StackNavigator,完全符合React Navigation的嵌套规则 - 保留了react-native-paper的
Icon组件,确保底部导航的图标样式和之前一致
备注:内容来源于stack exchange,提问作者Durgesh Tambe

