React native:TypeError:null 不是对象(评估“SplashScreen.preventAutoHide”)
在使用
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
AppLoading 组件 在裸工作流程中不可用。正如 @gaurav-roy 所说,您必须重构代码。
-
使用
npm install expo-splash-screen
安装expo-splash-screen
包 -
向您的 Android 和 iOS 项目添加启动画面。运行
npm run expo-splash-screen --help
并按照此 CLI 工具的说明进行操作。 (由于存在错误,如果运行该命令后只添加了 Android 版 SplashScreen,则可能必须使用-p "ios"
标志再次运行该命令。 -
按照与 此示例 中类似的方式更改
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>;
}
从文档中可以明显看出,SplashScreen 是 expo 应用程序的内置 api,由于您将其弹出,因此它会引发错误,因为它无法使用。
您可以在文档 expo splashscreen 中看到这一点。
首先,您应该下载
npm i expo-splash-screen
然后将您的导入语句更改为:
import * as SplashScreen from 'expo-splash-screen';
希望对您有所帮助。如有疑问,请随意
浏览完此 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",
},
});