You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>
  );
}

报错原因分析

  1. 未定义/未导入的组件:导航器中Drawer.Screen的TheGuysScreen既没有导入,也没有在文件内定义,导致component={TheGuysScreen}传入undefined,这是触发警告的直接原因。
  2. 导入导出不匹配风险:虽然LoginScreen的命名导出与导入方式正确,但其他组件(如CaseloadScreen)若存在导出方式与导入方式不匹配(默认导出却用花括号导入,或反之),也会导致类似错误。
  3. navigation参数传递错误:DrawerNavigation作为NavigationContainer的直接子组件,无法自动获取navigation props,会导致headerLeft中的navigation.toggleDrawer()调用失败,虽不是当前警告的直接原因,但会引发后续错误。

解决方法

  1. 修复TheGuysScreen引用:

    • 若该组件存在,添加导入语句:
      import { TheGuysScreen } from '../screens/TheGuysScreen';
      
    • 若已废弃,直接删除对应的Drawer.Screen代码块。
  2. 统一导入导出规范:

    • 组件用默认导出(export default function XxxScreen() {})时,导入去掉花括号:import XxxScreen from '../screens/XxxScreen';
    • 组件用命名导出(export const XxxScreen = () => {})时,导入保留花括号:import { XxxScreen } from '../screens/XxxScreen';
  3. 修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 09:11:53