React Native报错:React.jsx类型无效,获取值为undefined
解决React Native中「Warning: React.jsx: type is invalid -- expected a string or class/function but got: undefined」报错
重构React Native应用后出现上述警告,推测与文件导入/导出方式有关,相关代码如下:
根组件App.jsx
import React, { useState, useEffect } from 'react'; import Navigator from './navigation/navigator'; import { LoginScreen } from './screens/LoginScreen'; export default function App() { const [isLoggedIn, setIsloggedIn] = useState(false); useEffect(() => { setTimeout(() => { setIsloggedIn(true); }, 3000); }, []); return ( isLoggedIn ? ( <Navigator /> ) : ( <LoginScreen /> ) ); }
导航器navigator.jsx
import React from 'react'; import { StyleSheet, View, Feather } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createDrawerNavigator, DrawerContentScrollView, DrawerItemList, DrawerItem, } from '@react-navigation/drawer'; import { LoginScreen } from '../screens/LoginScreen'; import { CaseloadScreen } from '../screens/CaseloadScreen'; import { PatientScreen } from '../screens/PatientScreen'; import { WeeklyScreen } from '../screens/WeeklyScreen'; import { ProfileScreen } from '../screens/ProfileScreen'; import { Ionicons, FontAwesome, MaterialCommunityIcons, AntDesign } from '@expo/vector-icons'; import { AvailablePatientScreen } from '../screens/AvailablePatientScreen'; const CustomDrawerContent = (props) => { return ( <DrawerContentScrollView {...props}> <DrawerItemList {...props} style={{ activeTintColor: { color: '#fff', }, }} /> </DrawerContentScrollView> ); } const Drawer = createDrawerNavigator(); const DrawerNavigation = ({ navigation }) => { const icons = { tintColor: '#fff', size: 20, } return ( <Drawer.Navigator initialRouteName={'Caseload'} drawerContent={(props) => <CustomDrawerContent {...props} />} options={{ headerLeft: ( <View> <Feather name='menu' size={24} onPress={() => navigation.toggleDrawer()} color={'blue'} style={{}} /> </View> ), }} screenOptions={{ labelStyle: { color: '#fff', }, inactiveTintColor: { color: '#fff', }, drawerStyle: { backgroundColor: 'rgb(61,77,138)', width: 240, activeTintColor: 'rgb(61,77,138)', activeBackgroundColor: '#fff', inactiveTintColor: '#fff', inactiveBackgroundColor: 'rgb(61,77,138)', }, }} > <Drawer.Screen name="Caseload" component={CaseloadScreen} options={{ drawerIcon: () => (<Ionicons name="ios-home" size={icons.size} color={icons.tintColor} />) }} /> <Drawer.Screen name="Weekly Summary" component={WeeklyScreen} options={{ drawerIcon: () => (<FontAwesome name="bar-chart" size={icons.size} color={icons.tintColor} />) }} /> <Drawer.Screen name="Available RiverKids" component={AvailablePatientScreen} options={{ drawerIcon: () => (<FontAwesome name="child" size={icons.size} color={icons.tintColor} />) }} /> <Drawer.Screen name="My Profile" component={ProfileScreen} options={{ drawerIcon: () => (<AntDesign name="profile" size={icons.size} color={icons.tintColor} />) }} /> <Drawer.Screen name="The Guys" component={TheGuysScreen} options={{ drawerIcon: () => (<Ionicons name="ios-chatbubbles" size={icons.size} color={icons.tintColor} />) }} /> <Drawer.Screen name="Patient" component={PatientScreen} options={{ drawerItemStyle: { display: 'none' }, headerShown: false, }} /> <Drawer.Screen name="Login" component={LoginScreen} options={{ title: 'Sign Out', drawerIcon: () => (<MaterialCommunityIcons name="logout" size={icons.size} color={icons.tintColor} />) }} /> </Drawer.Navigator> ); } export default function Navigator() { return ( <NavigationContainer> <DrawerNavigation /> </NavigationContainer> ); }
LoginScreen.jsx
import { TouchableWithoutFeedback, Text, TextInput, KeyboardAvoidingView, Keyboard, View, Image, Button, } from 'react-native'; import styles from '../styles'; import { GradientButton } from '../components/GradientButton'; export const LoginScreen = (props) => { console.log('props: ', props); return ( <TouchableWithoutFeedback onPress={Keyboard.dismiss} > <View style={styles.login.container}> // Other code </View> </TouchableWithoutFeedback> ); }
报错原因分析
- 未定义/未导入的组件:导航器中
Drawer.Screen的TheGuysScreen既没有导入,也没有在文件内定义,导致component={TheGuysScreen}传入undefined,这是触发警告的直接原因。 - 导入导出不匹配风险:虽然
LoginScreen的命名导出与导入方式正确,但其他组件(如CaseloadScreen)若存在导出方式与导入方式不匹配(默认导出却用花括号导入,或反之),也会导致类似错误。 - navigation参数传递错误:
DrawerNavigation作为NavigationContainer的直接子组件,无法自动获取navigationprops,会导致headerLeft中的navigation.toggleDrawer()调用失败,虽不是当前警告的直接原因,但会引发后续错误。
解决方法
修复TheGuysScreen引用:
- 若该组件存在,添加导入语句:
import { TheGuysScreen } from '../screens/TheGuysScreen'; - 若已废弃,直接删除对应的
Drawer.Screen代码块。
- 若该组件存在,添加导入语句:
统一导入导出规范:
- 组件用默认导出(
export default function XxxScreen() {})时,导入去掉花括号:import XxxScreen from '../screens/XxxScreen'; - 组件用命名导出(
export const XxxScreen = () => {})时,导入保留花括号:import { XxxScreen } from '../screens/XxxScreen';
- 组件用默认导出(
修复navigation获取方式:
使用useNavigation钩子替代props传递,修改DrawerNavigation:import { useNavigation } from '@react-navigation/native'; const DrawerNavigation = () => { const navigation = useNavigation(); const icons = { tintColor: '#fff', size: 20, } return ( <Drawer.Navigator initialRouteName={'Caseload'} drawerContent={(props) => <CustomDrawerContent {...props} />} screenOptions={{ headerLeft: () => ( <View> <Feather name='menu' size={24} onPress={() => navigation.toggleDrawer()} color={'blue'} style={{}} /> </View> ), labelStyle: { color: '#fff' }, inactiveTintColor: '#fff', drawerStyle: { backgroundColor: 'rgb(61,77,138)', width: 240, activeTintColor: 'rgb(61,77,138)', activeBackgroundColor: '#fff', inactiveTintColor: '#fff', inactiveBackgroundColor: 'rgb(61,77,138)', }, }} > {/* 屏幕定义保持不变 */} </Drawer.Navigator> ); }注意:原代码中
Drawer.Navigator的options属性需改为screenOptions,因为options是单个屏幕的配置,screenOptions才是全局导航器的配置项。
内容的提问来源于stack exchange,提问作者Muirik
相关产品推荐
相关产品推荐

