React Navigation v6:从头部按钮打开模态框报错求助
问题分析
你遇到的TypeError: Cannot read property 'navigate' of undefined错误有两个核心原因:
- 根组件App无navigation属性:App是包裹
NavigationContainer的顶层组件,不属于任何导航器的屏幕,因此它的props里不会有navigation对象,直接调用navigation.navigate必然报错。 - 导航结构与模态注册错误:你未将
ScreenModal注册到导航器中,同时Tab导航器默认是底部标签结构,无法直接承载模态视图,需要通过嵌套栈导航实现正确的模态层级。
修复方案
按以下步骤修改代码即可解决问题:
1. 引入栈导航器
首先导入React Navigation的栈导航器:
import { createNativeStackNavigator } from '@react-navigation/native-stack';
2. 重构Tab导航组件
将原Tab导航逻辑抽离为独立组件,并在ScreenB的options中通过参数解构获取navigation对象:
const Stack = createNativeStackNavigator(); const Tab = createBottomTabNavigator(); // 独立的Tab导航组件 function TabNavigator() { return ( <Tab.Navigator> <Tab.Group> <Tab.Screen name="ScreenA" component={ScreenA} /> </Tab.Group> <Tab.Group> <Tab.Screen name="ScreenB" component={ScreenB} options={({ navigation }) => ({ headerRight: () => ( <Button onPress={() => navigation.navigate('ScreenModal')} title="Open Modal" /> ), })} /> </Tab.Group> <Tab.Group> <Tab.Screen name="ScreenC" component={ScreenC} /> </Tab.Group> </Tab.Navigator> ); }
3. 调整根组件导航结构
用栈导航器包裹Tab导航器,同时注册ScreenModal并设置模态展示样式:
export default function App() { // 根组件无需接收navigation props return ( <NavigationContainer> <Stack.Navigator> {/* Tab导航作为栈的主页面,隐藏默认头部 */} <Stack.Screen name="MainTabs" component={TabNavigator} options={{ headerShown: false }} /> {/* 注册模态屏幕,设置presentation为modal实现模态交互 */} <Stack.Screen name="ScreenModal" component={ScreenModal} options={{ presentation: 'modal' }} /> </Stack.Navigator> </NavigationContainer> ); }
完整修复代码
import React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { Button, Text, View} from 'react-native'; // Import Tab Screens import ScreenA from './src/pages/screenA' import ScreenB from './src/pages/screenB' import ScreenC from './src/pages/screenC' const Stack = createNativeStackNavigator(); const Tab = createBottomTabNavigator(); function ScreenModal({ navigation }) { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>This is a modal!</Text> <Button onPress={() => navigation.goBack()} title="Dismiss" /> </View> ); } function TabNavigator() { return ( <Tab.Navigator> <Tab.Group> <Tab.Screen name="ScreenA" component={ScreenA} /> </Tab.Group> <Tab.Group> <Tab.Screen name="ScreenB" component={ScreenB} options={({ navigation }) => ({ headerRight: () => ( <Button onPress={() => navigation.navigate('ScreenModal')} title="Open Modal" /> ), })} /> </Tab.Group> <Tab.Group> <Tab.Screen name="ScreenC" component={ScreenC} /> </Tab.Group> </Tab.Navigator> ); } export default function App() { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="MainTabs" component={TabNavigator} options={{ headerShown: false }} /> <Stack.Screen name="ScreenModal" component={ScreenModal} options={{ presentation: 'modal' }} /> </Stack.Navigator> </NavigationContainer> ); }
关键说明
- 正确获取navigation:在
Tab.Screen的options中通过函数参数解构({ navigation })获取导航对象,而非从根组件props中读取。 - 模态层级逻辑:将Tab导航器嵌套在栈导航器中,让模态屏幕处于Tab导航的上层,确保模态覆盖整个界面,符合交互预期。
- 模态展示配置:通过
presentation: 'modal'指定屏幕以模态形式呈现(从底部滑入、覆盖全屏)。
内容的提问来源于stack exchange,提问作者Learner-Driver
相关产品推荐
相关产品推荐

