首页 > 解决方案 > 更新博览会后:元素类型无效:需要字符串(用于内置组件)或类/函数

问题描述

在我将 Expo SDK 从 39 更新到 42 后,尝试启动应用程序时出现以下错误:

错误:元素类型无效:应为字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义。您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。

检查App.

此错误位于: App 中(由 ExpoRoot 创建) ExpoRoot 中(renderApplication.js:45) RCTView 中(View.js:34)中 RCTView 中的 View(AppContainer.js:106)中(View.js :34) 在视图中 (在 AppContainer.js:132) 在 AppContainer (在 renderApplication.js:39)

从错误报告中我得出结论,该错误位于我的 App.js 文件中,即使除了升级我的 expo 版本之外我没有更改任何内容。

应用程序.js:

//Automatic imports
import React, {useState} from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Provider } from 'react-redux';

//My imports
import * as Font from 'expo-font';
import {AppLoading} from 'expo';
import ReduxThunk from 'redux-thunk';
import { createStore, combineReducers, applyMiddleware } from 'redux';


//import other screens
import NavigationContainer from './navigation/NavigationContainer';

//import Reducers
import authReducer from './store/reducers/auth';
import pigeonReducer from './store/reducers/pigeon';
import badgesReducer from './store/reducers/badges';
import languagesReducer from './store/reducers/language';

//imports related to firebase
import * as firebase from "firebase";
import ApiKeys from "./constants/ApiKeys";

//Loading Fonts, returns promise
const fetchFonts = () => {
  return Font.loadAsync({
    'Magnus' : require('./assets/fonts/MagnusText.ttf'),
    'AmaticBold' : require('./assets/fonts/Amatic-Bold.ttf'),
    'AmaticRegular' : require('./assets/fonts/AmaticSC-Regular.ttf'),
    'SEASRN' : require('./assets/fonts/SEASRN.ttf'),
    'Otto' : require('./assets/fonts/Otto.ttf'),
    'Gwibble' : require('./assets/fonts/GWIBBLE.ttf'),
    'GTA' : require('./assets/fonts/pricedown.otf')
  });
};

const rootReducer = combineReducers({
  auth: authReducer,
  myPigeons: pigeonReducer,
  myBadges: badgesReducer,
  myLanguage: languagesReducer
});

const store = createStore(rootReducer, applyMiddleware(ReduxThunk));


export default function App() {
  //firebase project initialisation
  if (!firebase.apps.length) {
    firebase.initializeApp(ApiKeys);
    //console.log("DB INITIALISED"); FIRING IF DATABASE INITIALISED
  };

  const [dataLoaded, setDataLoaded] = useState(false); //are fonts loaded?

  if(!dataLoaded){ //will go into if clause because fonts are not loaded
    return(
      <AppLoading 
        startAsync={fetchFonts} 
        onFinish={() => setDataLoaded(true)}
        onError={(err) => console.log(err)}
      />
    )
  }
  return (
    <Provider store={store}>
      <NavigationContainer/>
    </Provider>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

我知道有几个人遇到了同样的错误,但是他们的问题有很多答案对我不起作用,也许有人知道如何解决我的问题。如果您需要我项目中的其他代码示例,请告诉我,我会更新这个问题。

标签: javascriptreact-nativeexpo

解决方案


99% 的情况下,此错误意味着您正在Xyz从某个地方导入,但它实际上并不作为导出存在。

因此,当您尝试<Xyz ... />在 JSX 中执行操作时,您会收到错误,我将在此处重现:

错误:元素类型无效:需要一个字符串(对于内置组件)或一个类/函数(对于复合组件),但得到:undefined。您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。

(强调我的)

undefined是这里的关键,例如你有

import {AppLoading} from 'expo';

然而,根据当前文档的行是

import AppLoading from 'expo-app-loading';

要对此进行调试,只需记录导入的组件即可:

console.log(AppLoading);

您会很快找到undefined导致错误的导入。


推荐阅读