反应本机:TypeError:空不是对象(正在评估'SplashScreen.preventAutoHide')

时间:2020-04-06 19:01:11

标签: ios react-native expo

在我使用expo eject之前,我的react native应用运行良好。我之所以将其弹出是因为我现在打算构建该应用并将其发布到ios应用商店中。弹出后,我一尝试使用react-native run-ios启动弹出的应用程序,就会在下面看到异常。

请有人帮助您了解导致此问题的原因以及如何解决此问题?

对本机版本的反应如下:

react-native-cli: 2.0.1
react-native: 0.61.5

enter image description here

TypeError: null is not an object (evaluating 'SplashScreen.preventAutoHide')

This error is located at:
    in AppLoading (at AppLoading.js:52)
    in AppLoading (at App.js:464)
    in App (at renderApplication.js:40)
    in RCTView (at AppContainer.js:101)
    in RCTView (at AppContainer.js:119)
    in AppContainer (at renderApplication.js:39)

preventAutoHide
    SplashScreen.js:4:21
AppLoading#constructor
    AppLoadingNativeWrapper.js:6:8
renderRoot
    [native code]:0
runRootCallback
    [native code]:0
renderApplication
    renderApplication.js:52:52
runnables.appKey.run
    AppRegistry.js:116:10
runApplication
    AppRegistry.js:197:26
callFunctionReturnFlushedQueue
    [native code]:0

5 个答案:

答案 0 :(得分:10)

AppLoading component在裸露的工作流程中不可用。正如@ gaurav-roy所说,您必须重构代码。

  1. 使用expo-splash-screen安装npm install expo-splash-screen软件包

  2. 向您的Android和iOS项目添加初始屏幕。运行npm run expo-splash-screen --help,然后按照此CLI工具的说明进行操作。 (由于存在错误,如果仅在运行后添加用于Android的SplashScreen,则可能必须使用-p "ios"标志再次运行该命令。

  3. 以与this example中类似的方式在App.tsx中更改代码。

    如果使用的是钩子,则可能要添加一个useEffect 带有空的依赖项列表的钩子,该列表运行异步函数。这是一个如何完成的示例:

const App = (props: Props) => {
  const [isLoadingComplete, setLoadingComplete] = useState(false);
  
  const init = async () => {
  try {
    // Keep on showing the SlashScreen
    await SplashScreen.preventAutoHideAsync();
    await loadResourcesAsync();
  } catch (e) {
    console.warn(e);
  } finally {
    setLoadingComplete(true);
    // Hiding the SplashScreen
    await SplashScreen.hideAsync();
  }
  
  useEffect(() => {
    init();
  }, []);

  const renderApp = () => {
    if (!isLoadingComplete && !props.skipLoadingScreen) {
      return null;
    }

    return (
      <Main />
    );
  };
  return <StoreProvider>{renderApp()}</StoreProvider>;
}

答案 1 :(得分:3)

从docs可以明显看出,SplashScreen是用于expo应用程序的内置api,由于您将其弹出,因此无法使用它会引发错误。

您可以在文档expo splashscreen中看到此内容。

首先,您应该下载npm i expo-splash-screen

然后将导入语句更改为:

import * as SplashScreen from 'expo-splash-screen';

希望有帮助。毫无疑问

答案 2 :(得分:1)

浏览了此SO页面,然后深入研究了某些链接,尤其是this博览会页面,他们为此提供了解决方案,经过大约3个小时的努力,我得以使我的应用程序运行。他们还没有添加任何功能组件示例,因此,如果有人来这里寻求解决方案,我将在下面共享我的代码。

import { Asset } from "expo-asset";
import * as Font from "expo-font";
import React, { useState, useEffect } from "react";
import { Platform, StatusBar, StyleSheet, View } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import * as SplashScreen from 'expo-splash-screen';

import AppNavigator from "./navigation/AppNavigator";

export default props => {
  const [isLoadingComplete, setLoadingComplete] = useState(false);

  const theme = {
    ...DefaultTheme,
    roundness: 2,
    colors: {
      ...DefaultTheme.colors,
      primary: "#E4002B",
      accent: "#E4002B",
    },
  };

  useEffect(() => {
    async function asyncTasks() {
      try {
        await SplashScreen.preventAutoHideAsync();
      } catch (e) {
        console.warn(e);
      }
      await loadResourcesAsync()
      setLoadingComplete(true);
    }

    asyncTasks()
  }, []);

  return (
    !isLoadingComplete && !props.skipLoadingScreen ? null :
    <View style={styles.container}>
      {Platform.OS === "ios" && <StatusBar barStyle="default" />}
      <AppNavigator />
    </View>
  );
}

async function loadResourcesAsync() {
  await Promise.all([
    Asset.loadAsync([
      require("./assets/images/logo.png") // Load your resources here (if any)
    ]),
    Font.loadAsync({
      // You can remove this if you are not loading any fonts
      "space-mono": require("./assets/fonts/SpaceMono-Regular.ttf"),
    }),
  ]);
  await SplashScreen.hideAsync();
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
  },
});

答案 3 :(得分:1)

这为弹出的博览会应用程序为我解决了。好像expo错误地引用了它。 https://github.com/expo/expo/issues/7718#issuecomment-610508510

答案 4 :(得分:-1)

对我有用的是按照adamsolomon1986 in the repo (issue #7718)的建议将node_modules / expo / build / launch / splashScreen.js更新为以下内容:

import { NativeModules } from 'react-native';
import* as SplashScreen from 'expo-splash-screen'
export function preventAutoHide() {
    if (SplashScreen.preventAutoHide) {
        SplashScreen.preventAutoHide();
    }
}
export function hide() {
    if (SplashScreen.hide) {
        SplashScreen.hide();
    }
}
//# sourceMappingURL=SplashScreen.js.map