expo with splash-screen for react-native

536 views Asked by At

I am using react-native with expo and splash screen.

I want to use some local fonts, and I encountered problems that probably related to expo version of react-native.

In package.json:

    "dependencies": {
      "expo": "~48.0.15",
      "expo-font": "^11.6.0",
      "expo-linear-gradient": "~12.3.0",
      "expo-status-bar": "~1.6.0",
      "react": "18.2.0",
      "react-dom": "18.2.0",
      "react-native": "^0.72.6",
      "react-native-web": "~0.19.6",
      "expo-splash-screen": "~0.18.2"
    }

I am using expo-splash-screen, since expo-app-loading is deprecated (also expo need not to install globally - it is not global installed right now).

Also installation for expo:

npx expo install <expo-package-name>

In code:

    import SplashScreen from 'expo-splash-screen';
    export default function App() {
    ...
    async function prepare() {
        try {
            // Keep the splash screen visible while we fetch resources
            console.log("****step 1");
            await SplashScreen.preventAutoHideAsync(); // *** The problem.
            console.log("*****step 2");
            // Pre-load fonts, make any API calls you need to do here
            await Font.loadAsync({
            'openSans': require('./assets/fonts/OpenSans-Regular.ttf'),
            'openSansBold': require('./assets/fonts/OpenSans-Bold.ttf'),
        });
        }
        catch(e) {
        // console.warn(e);
        } finally {
            console.log("*****step 3");
            setAppIsReady(true);
            console.log("*****step 4");
            await SplashScreen.hideAsync();
            console.log("*****step 5");
        }
    }
    prepare();
    }, []);
    if (!appIsReady) {
        return null;
    }

... step 2 never occured ... So just after, the program:

    await SplashScreen.preventAutoHideAsync();

I got warning:

TypeError: Cannot read property: 'preventAutoHideAsync' of undefined.

Exception I got:

Possible Unhandled promose Rejection (id: 0): TypeErrorr: cannot read property 'hideAsync' of undefined.

I have IOS. I thought this is an IOS issue, but for android I got the same message as well.

IOS issue

Android emulator exception:

Android emulator exception

I did log like this:

console.log(SplashScreen);

and got as a result: undefined.

As I searched, there may be need to run: npx pod-install (i.e. Pod install recommendation)

For windows: npx pod-install returns:

CocoaPods is only supported on darwin machines

Is that the problem? Can it run in windows, anyway? AFAIK, darwin machines are macos, but when using expo - it should enable this on windows (running on windows solved by expo)

I have an iphone, so my code runs on iphone (but the code is written on windows environment machine).

What may be the fix for that?

2

There are 2 answers

0
Eitan On BEST ANSWER

As for the source - there were few mistakes, maily that:

import SplashScreen from 'expo-splash-screen';

is incorrect, and should be :

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

The decrlarations for package.json are fine.

Here is a full code with correction, as I realized from SplashScreen - Expo Documentation

...
import * as SplashScreen from 'expo-splash-screen';
import * as Font from 'expo-font';
...
SplashScreen.preventAutoHideAsync();

export default function App() {
  const [appIsReady, setAppIsReady] = useState(false);
  useEffect(() => {
    async function prepare() {
      try {
        ...
        await <Promise>; 
        ...
        await Font.loadAsync({
          'open-sans': require('./assets/fonts/OpenSans-Regular.ttf'),
          'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'),
        });
        ...

      } catch (e) {
        console.warn(e);
      } finally {
        setAppIsReady(true);  
      }

    prepare();

  }, []);


   
  const onLayoutRootView = useCallback(async () => {
    if (appIsReady) {
      await SplashScreen.hideAsync();
    }
  }, [appIsReady]);

  if (!appIsReady) {
    return null;
  }



  return (
    <>
      <NavigationContainer onReady={onLayoutRootView}> ...
    </>
  );
}

For view (instead of navigation container, there may be change for the readiness state), i.e. :

<View onLayoutRootView={onLayoutRootView} > ...
9
Boyan Boyanov On

I don't think you have to wait for SplashScreen.preventAutoHideAsync(). Check the docs https://docs.expo.dev/versions/latest/sdk/splash-screen/#usage

There is also a hook from expo-font - useFonts - which returns a boolean to indicate when the fonts are loaded. You can check it out here https://docs.expo.dev/versions/latest/sdk/font/#usage

If you stick to one of the examples I believe you will be ok :)