开发者问题收集

React native:TypeError:null 不是对象(评估“SplashScreen.preventAutoHide”)

2020-04-06
12161

在使用 expo pop 之前,我的 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
3个回答

AppLoading 组件 在裸工作流程中不可用。正如 @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. 按照与 此示例 中类似的方式更改 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
2020-04-08

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

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

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

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

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

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

Gaurav Roy
2020-04-07

浏览完此 SO 页面,然后深入研究了一些链接,尤其是 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",
  },
});
Hashir Baig
2020-06-15