升级React Navigation 4至6后应用加载失败,默认导入引发未定义错误
问题分析
升级至React Navigation 6后出现的未定义错误,大概率是以下原因之一:
- 类组件未正确获取
navigation属性:多层HOC(如connect和translate)可能拦截或丢失navigation属性传递。 - Action Creator导出方式错误:若
lojas、pushTokens等模块的action creator使用默认导出而非命名导出,会导致...lojas.actions展开时出现未定义。 - 依赖版本不兼容:Expo SDK 44与React Navigation 6的依赖版本未匹配。
解决方案
1. 修正Action Creator导出方式
检查lojas/actions.js、pushTokens/actions.js等文件,确保所有action creator均为命名导出:
// 正确写法(命名导出) export const recuperarLojaFavorita = () => ({ type: 'RECUPERAR_LOJA_FAVORITA' }); // 错误写法(默认导出,会导致lojas.actions.recuperarLojaFavorita未定义) export default recuperarLojaFavorita;
因为lojas/index.js中使用import * as actions from './actions',只有命名导出的action才会被包含在lojas.actions对象中。
2. 确保navigation属性正常传递
若navigation属性未被传递到ConfigsLoading组件,可尝试以下两种方式:
方式一:调整HOC包裹顺序
将connect放在translate之前,避免Redux拦截navigation属性:
// 原代码 const obj = translate(['common'], { wait: true })(ConfigsLoading); export default connect(mapStateToProps, { ...lojas.actions, ...pushTokens.actions, ...usuarios.actions, ...campanhas.actions })(obj); // 修改后 const connectedComponent = connect(mapStateToProps, { ...lojas.actions, ...pushTokens.actions, ...usuarios.actions, ...campanhas.actions })(ConfigsLoading); export default translate(['common'], { wait: true })(connectedComponent);
方式二:使用navigationRef(推荐用于类组件)
React Navigation 6已废弃withNavigation HOC,可通过全局navigationRef访问导航功能:
- 在RoutesNavigators.js中添加并导出ref:
import * as React from 'react'; import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import ConfigsLoading from './screens/commons/configs_loading'; export const navigationRef = useNavigationContainerRef(); const Stack = createNativeStackNavigator(); const RoutesNavigator = () => ( <NavigationContainer ref={navigationRef}> <Stack.Navigator initialRouteName="ConfigsLoading" screenOptions={{ headerShown: false }}> <Stack.Screen name="ConfigsLoading" component={ConfigsLoading} /> </Stack.Navigator> </NavigationContainer> ); export default RoutesNavigator;
- 创建导航工具类(如
navigationService.js):
import { navigationRef } from './RoutesNavigators'; export const navigate = (routeName, params) => { if (navigationRef.isReady()) { navigationRef.navigate(routeName, params); } };
- 在ConfigsLoading中使用:
import { navigate } from '../../../navigationService'; // 替代this.props.navigation.navigate('RouteName') navigate('RouteName', { params });
同时可移除propTypes中navigation的必填校验,避免不必要的错误。
3. 确认依赖版本兼容性
执行以下命令安装Expo SDK 44兼容的React Navigation 6依赖:
expo install @react-navigation/native @react-navigation/native-stack react-native-screens react-native-safe-area-context
SDK 44对应的兼容版本为:
@react-navigation/native: ^6.0.0@react-navigation/native-stack: ^6.0.0react-native-screens: ~3.10.1react-native-safe-area-context: ~3.3.2
调试建议
在ConfigsLoading的构造函数中添加日志,查看实际接收的props:
constructor(props) { super(props); console.log('Received props:', props); // 检查是否包含navigation、action creators等 this.state = {}; }
根据日志结果定位具体未定义的属性,针对性修复。
内容的提问来源于stack exchange,提问作者Gustavo Juneo Santos
相关产品推荐
相关产品推荐

