【问题标题】:React native: TypeError: null is not an object (evaluating 'SplashScreen.preventAutoHide')反应本机:TypeError:null 不是对象(评估'SplashScreen.preventAutoHide')
【发布时间】:2020-07-18 21:07:45
【问题描述】:

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

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

React Native 版本如下:

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

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

【问题讨论】:

标签: ios react-native expo


【解决方案1】:

这为我解决了弹出的 expo 应用程序的问题。看起来世博会错误地引用它。 https://github.com/expo/expo/issues/7718#issuecomment-610508510

【讨论】:

    【解决方案2】:

    在浏览了这个 SO 页面,然后深入研究了一些链接,尤其是 this expo 页面,他们为此提供了一种解决方案,经过大约 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】:

      对我有用的是按照 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
      

      【讨论】:

      • 更改node_modules 文件夹中的文件绝不是一个好主意。每当您重新安装依赖项时,更改都会消失。
      • @Andru,感谢您的提醒;我得看那个。太糟糕了,这是我发现唯一有效的方法:/
      • @Matthew 如果你绝对必须这样做 - 你应该使用 patch-package.github.com/ds300/patch-package
      【解决方案4】:

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

      1. 使用npm install expo-splash-screen 安装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>;
      }
      

      【讨论】:

      • 干杯 @andru - 我尝试使用您提到的命令自动生成启动画面,但该命令已经挂了很长时间,所以最终我决定手动创建它。
      • @user3391835 我也遇到了同样的情况。虽然它挂起,但它正在创建 Android 屏幕。然后使用我提到的-p "ios" 选项再次运行该命令。然后它将创建 iOS 启动画面。试一试。
      • 好的 - 太好了。非常感谢 - 会试试这个
      • 我们是否必须为应用程序使用 expo 启动画面?
      • @KehlinSwain 不,你没有。你也可以使用github.com/crazycodeboy/react-native-splash-screen
      【解决方案5】:

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

      您可以在文档 expo splashscreen 中看到这一点。

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

      然后将您的导入语句更改为:

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

      希望对您有所帮助。如有疑问,请随意

      【讨论】:

      • 我从来没有在任何地方导入 SplashScreen 却得到同样的错误。安装expo-splash-screen后依然存在
      • 对我来说,我不得不去 node 模块内 expo build 文件夹的路径并替换以前的导入方法。
      • 这里是路径:node_modules/expo/build/launch/splashScreen.js
      猜你喜欢
      • 1970-01-01
      • 2021-01-13
      • 2020-11-21
      • 2021-05-27
      • 2021-12-29
      • 2020-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多