React Navigation嵌套栈导航报错:路由组件需为React组件的解决方法
这个报错的根源很清晰:你现在的Profile文件默认导出的是导航容器(createAppContainer的返回值),而不是Profile页面组件本身。当你在AppSignInNav的栈配置里指定Profile: { screen: Profile }时,你实际上传入了一个完整的导航容器,而React Navigation要求栈的screen必须是一个纯React页面组件,或者另一个未被容器包裹的导航栈,所以才会抛出"The component for route 'Profile' must be a React component..."的错误。
下面提供两种可行的解决方案,你可以根据项目结构选择:
方案一:统一在根目录管理所有导航栈(推荐)
这种方式更清晰,避免每个页面文件单独创建导航容器,适合中小型项目的导航结构。
1. 创建根导航文件(比如RootNavigator.js)
把所有页面和子栈都集中在这里配置:
import { createStackNavigator, createAppContainer } from 'react-navigation'; import AppSignIn from './path/to/AppSignIn'; import Profile from './path/to/Profile'; import Inbox from './path/to/Inbox'; // 先创建Profile和Inbox的子栈 const ProfileStack = createStackNavigator({ Profile: { screen: Profile }, Inbox: { screen: Inbox } }); // 创建根栈,包含SignIn页面和Profile子栈 const RootStack = createStackNavigator({ AppSignIn: { screen: AppSignIn }, ProfileStack: { screen: ProfileStack } }); // 根导航只需要一个容器 export default createAppContainer(RootStack);
2. 修改AppSignIn.js
移除文件内的导航栈配置,只保留页面组件,并修改导航目标为ProfileStack:
import React from 'react'; import { View, TouchableHighlight, Text } from 'react-native'; class AppSignIn extends React.Component { _doSignIn() { // 导航到Profile子栈 this.props.navigation.navigate('ProfileStack'); } render() { return ( <View> <TouchableHighlight onPress={this._doSignIn.bind(this)}> <Text>Go to Profile</Text> </TouchableHighlight> </View> ); } } export default AppSignIn;
3. 修改Profile.js
移除文件内的导航栈和容器配置,只保留页面组件:
import React from 'react'; import { View, TouchableHighlight, Text } from 'react-native'; class Profile extends React.Component { _goToInbox() { // 直接导航到当前子栈内的Inbox页面 this.props.navigation.navigate('Inbox'); } render() { return ( <View> <TouchableHighlight onPress={this._goToInbox.bind(this)}> <Text>Go to Inbox</Text> </TouchableHighlight> </View> ); } } export default Profile;
方案二:保留页面内的子栈,但避免嵌套导航容器
如果你希望每个模块保留自己的导航栈,可以调整导出方式,不要把导航栈包裹在createAppContainer里:
1. 修改Profile.js的导出
同时导出页面组件和未被容器包裹的导航栈:
import React from 'react'; import { View, TouchableHighlight, Text } from 'react-native'; import Inbox from "../Inbox"; // 导出Profile页面组件 export class Profile extends React.Component { _goToInbox() { this.props.navigation.navigate('Inbox'); } render() { return ( <View> <TouchableHighlight onPress={this._goToInbox.bind(this)}> <Text>Go to Inbox</Text> </TouchableHighlight> </View> ); } } // 导出未被容器包裹的导航栈 export const ProfileNav = createStackNavigator({ Profile: { screen: Profile }, Inbox: { screen: Inbox } }); // 不要在这里使用createAppContainer!
2. 修改AppSignIn.js的导航配置
导入ProfileNav作为栈的目标,而不是Profile组件:
import React from 'react'; import { View, TouchableHighlight, Text } from 'react-native'; import { createStackNavigator, createAppContainer } from 'react-navigation'; import { ProfileNav } from "../Profile"; class AppSignIn extends React.Component { _doSignIn() { this.props.navigation.navigate('ProfileNav'); } render() { return ( <View> <TouchableHighlight onPress={this._doSignIn.bind(this)}> <Text>Go to Profile</Text> </TouchableHighlight> </View> ); } } const AppSignInNav = createStackNavigator( { AppSignIn: { screen: AppSignIn }, ProfileNav: { screen: ProfileNav } } ); export default createAppContainer(AppSignInNav);
两种方案都能解决你的问题,核心原则就是:导航容器(createAppContainer的结果)只能作为整个应用的根导航,不能作为另一个栈的screen使用。
内容的提问来源于stack exchange,提问作者Africa Matji
相关产品推荐
相关产品推荐

