hello guy my app trow this error
AppLoading threw an unexpected error when loading:
Error: AppLoading onError prop is required if startAsync is provided
You can try to use a community AppLoading library; such as:
expo-app-loading
Also, you can reinstall the libraries.
In case, here’s my App.js:
import React, { useState } from 'react';
import AppLoading from 'expo-app-loading';
import { NavigationContainer } from '@react-navigation/native';
import AppNavigator from './app/navigation/AppNavigator';
import AuthContext from './app/auth/context';
import AuthNavigator from './app/navigation/AuthNavigator';
import NavigationTheme from './app/navigation/NavigationTheme';
import OfflineNotice from './app/components/OfflineNotice';
import authStorage from './app/auth/storage';
export default function App() {
const [user, setUser] = useState();
const [isReady, setIsReady] = useState(false);
const restoreUser = async () => {
const loginInfo = await authStorage.getUser();
if (loginInfo) setUser(loginInfo);
};
if (!isReady) {
return (
<AppLoading
startAsync={restoreUser}
onFinish={() => setIsReady(true)}
onError={console.warn}
/>
);
}
return (
<AuthContext.Provider value={{ user, setUser }}>
<OfflineNotice />
<NavigationContainer theme={NavigationTheme}>
{user ? <AppNavigator /> : <AuthNavigator />}
</NavigationContainer>
</AuthContext.Provider>
);
}
Since now AppLoading
is deprecated I’ll post my solution using the SplashScreen
module as suggested on the expo documentation.
First, install the SplashScreen module:
expo install expo-splash-screen
This is my App.js:
import React, { useCallback, useEffect, useState } from "react";
import { NavigationContainer } from "@react-navigation/native";
import jwtDecode from "jwt-decode";
import * as SplashScreen from "expo-splash-screen";
import AppNavigator from "./app/components/navigation/AppNavigator";
import AuthContext from "./app/auth/context";
import AuthNavigator from "./app/components/navigation/AuthNavigator";
import OfflineNotice from "./app/components/OfflineNotice";
import navigationTheme from "./app/components/navigation/navigationTheme";
import authStorage from "./app/auth/storage";
export default function App() {
const [user, setUser] = useState();
const [isReady, setIsReady] = useState(false);
const restoreToken = async () => {
const token = await authStorage.getToken();
if (!token) return;
setUser(jwtDecode(token));
};
useEffect(() => {
async function prepare() {
try {
await SplashScreen.preventAutoHideAsync();
await restoreToken();
} catch (error) {
console.log("Error loading app", error);
} finally {
setIsReady(true);
}
}
prepare();
}, []);
const onNavigationContainerReady = useCallback(async () => {
if (isReady) await SplashScreen.hideAsync();
}, [isReady]);
if (!isReady) return null;
return (
<AuthContext.Provider value={{ user, setUser }}>
<NavigationContainer theme={navigationTheme} onReady={onNavigationContainerReady}>
{user ? <AppNavigator /> : <AuthNavigator />}
</NavigationContainer>
<OfflineNotice />
</AuthContext.Provider>
);
}
hello~ what is the link to your repository? i really want to see the solution
Sorry I don’t have a repository online but all the changes regarding the splash screen are on the App.js file i posted above. You just need to install the expo-splash-screen module and look at my App.js.
If you review SplashScreen Documentation the Usage section seems pretty clear cut (aka…I implemented it in about 3 minutes).
@deedeedev , I had the same problem, so I tried to use your code, but for some reason onNavigationContainerReady()
was never fired.
Eventually, I made it by doing everything under useEffect:
(and then there is no need for onNavigationContainerReady()
and the isReady
hook)
useEffect(() => {
async function prepare() {
try {
await SplashScreen.preventAutoHideAsync();
await restoreToken();
} catch (error) {
console.log("Error loading app", error);
} finally {
await SplashScreen.hideAsync();
}
}
prepare();
}, []);
What is actually the risk of doing that?
import { jwtDecode } from "jwt-decode";
import "core-js/stable/atob";
import * as SplashScreen from "expo-splash-screen";
// ... Other imports
SplashScreen.preventAutoHideAsync();
export default function App() {
const [user, setUser] = useState();
const [isReady, setIsReady] = useState(false);
const restoreToken = async () => {
const token = await authStorage.getToken();
if (!token) return setIsReady(true);
setUser(jwtDecode(token));
setIsReady(true);
};
useEffect(() => {
restoreToken();
}, []);
const onLayoutRootView = useCallback(async () => {
if (isReady) {
await SplashScreen.hideAsync();
}
}, [isReady]);
if (!isReady) {
return null;
}
return (
<View
style={{ flex: 1 }}
onLayout={onLayoutRootView}
>
<AuthContext.Provider value={{ user, setUser }} >
<OfflineNotice />
<NavigationContainer theme={navigationTheme}>
{user ? <AppNavigator /> : <AuthNavigator />}
</NavigationContainer>
</AuthContext.Provider>
</View>
);