在我使用expo eject
之前,我的react native应用运行良好。我之所以将其弹出是因为我现在打算构建该应用并将其发布到ios应用商店中。弹出后,我一尝试使用react-native run-ios
启动弹出的应用程序,就会在下面看到异常。
请有人帮助您了解导致此问题的原因以及如何解决此问题?
对本机版本的反应如下:
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
答案 0 :(得分:10)
AppLoading component在裸露的工作流程中不可用。正如@ gaurav-roy所说,您必须重构代码。
使用expo-splash-screen
安装npm install expo-splash-screen
软件包
向您的Android和iOS项目添加初始屏幕。运行npm run expo-splash-screen --help
,然后按照此CLI工具的说明进行操作。 (由于存在错误,如果仅在运行后添加用于Android的SplashScreen,则可能必须使用-p "ios"
标志再次运行该命令。
以与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