React Navigation跳转Settings页面报错:navigate属性未定义
问题场景与报错
我已将所有页面包裹在NavigationContainer中,前5个页面配置为Bottom Tab导航,期望通过Profile页面(对应Score组件)内的设置按钮跳转到独立的Settings页面,但点击按钮时触发错误:
TypeError: Cannot read property 'navigate' of undefined, js engine: hermes
相关代码
RootNavigation代码
const Stack = createStackNavigator(); const RootNavigation = () => { return( <NavigationContainer> <Stack.Navigator screenOptions={{headerShown: false}}> <Stack.Screen name="Loop" component={BottomTabNavigator} /> <Stack.Screen name="Profile" component={BottomTabNavigator} /> //Profile screen is the rendering the "Score" component <Stack.Screen name="Compete" component={BottomTabNavigator} /> <Stack.Screen name="Diss" component={BottomTabNavigator} /> <Stack.Screen name="Feedback" component={BottomTabNavigator} /> <Stack.Screen name="Settings" component={SettingsNavigator} /> </Stack.Navigator> </NavigationContainer> ); }; export default RootNavigation;
SettingsNavigator.js代码
const SettingsNavigator = () => { return ( <Stack.Navigator> <Stack.Screen name={"Settings"} component={Settings} /> </Stack.Navigator> ); }; export default SettingsNavigator;
Settings页面代码
const Settings = () => { return ( <View> <SettingsPage /> </View> ); }; export default Settings;
SettingsPage组件代码
const SettingsPage = () => { return ( <View> <Text>Hello this is the settings page</Text> </View> ); }; export default SettingsPage;
Score组件代码
const Score = () => { return ( <View style={{ height: Dimensions.get('window').height, width: Dimensions.get('window').width, backgroundColor: '#1c1c1c' }}> <TouchableOpacity style={styles.settings}> <Ionicons name={'settings-outline'} size={30} color='white' onPress={() => Navigation.navigate('SettingsPage') } /> </TouchableOpacity> </View> ); }; export default Score;
问题原因与修复方案
核心问题
- 导航实例未正确获取:Score组件里直接用
Navigation.navigate,但没拿到React Navigation的导航对象,导致Navigation是undefined。 - 导航目标名称错误:Stack里注册的页面名叫
Settings,但代码里要跳的是SettingsPage,而且SettingsPage是Settings组件的子组件,不需要直接导航到它。 - RootNavigation结构冗余:前5个Stack页面都指向同一个
BottomTabNavigator,这会导致导航逻辑混乱,正确做法是把BottomTab作为Stack的一个根页面,而非重复注册5次。
修复步骤
步骤1:重构RootNavigation结构
把BottomTabNavigator作为Stack的唯一主页面,删除重复的Tab注册:
const Stack = createStackNavigator(); const RootNavigation = () => { return( <NavigationContainer> <Stack.Navigator screenOptions={{headerShown: false}}> {/* 只注册一次BottomTabNavigator作为主入口 */} <Stack.Screen name="MainTabs" component={BottomTabNavigator} /> <Stack.Screen name="Settings" component={SettingsNavigator} /> </Stack.Navigator> </NavigationContainer> ); }; export default RootNavigation;
同时确保你的BottomTabNavigator里已经正确配置了Loop、Profile、Compete、Diss、Feedback这5个Tab页面。
步骤2:在Score组件中正确获取导航对象
有两种可靠方式:
- 方式一:使用
useNavigation钩子(推荐)
import { useNavigation } from '@react-navigation/native'; const Score = () => { const navigation = useNavigation(); // 获取导航实例 return ( <View style={{ height: Dimensions.get('window').height, width: Dimensions.get('window').width, backgroundColor: '#1c1c1c' }}> <TouchableOpacity style={styles.settings}> <Ionicons name={'settings-outline'} size={30} color='white' onPress={() => navigation.navigate('Settings') } // 导航到Stack中注册的"Settings"页面 /> </TouchableOpacity> </View> ); }; export default Score;
- 方式二:通过props接收导航对象
如果Score是Tab页面的直接组件,导航对象会自动通过props传入,直接解构使用即可:
const Score = ({ navigation }) => { // 从props解构navigation return ( <View style={{ height: Dimensions.get('window').height, width: Dimensions.get('window').width, backgroundColor: '#1c1c1c' }}> <TouchableOpacity style={styles.settings}> <Ionicons name={'settings-outline'} size={30} color='white' onPress={() => navigation.navigate('Settings') } /> </TouchableOpacity> </View> ); }; export default Score;
步骤3:简化Settings导航层级(可选)
如果Settings页面不需要额外的Stack导航,可以删掉SettingsNavigator.js,直接在RootNavigation里注册Settings组件:
// 修改RootNavigation中的Settings页面注册 <Stack.Screen name="Settings" component={Settings} />
内容的提问来源于stack exchange,提问作者reactnativenerd
相关产品推荐
相关产品推荐

