You are currently viewing Build Splash Screen in React Native using Navigation v5

Build Splash Screen in React Native using Navigation v5

In this tutorial, I will explain how to create a simple splash screen using React Navigation v5 and LottieFiles

You can also see how to change the default Splash Screen in my new article.

In my project, I’m using version 17.0.1 for react and 0.64.0 for react-native.

Install React Navigation 5

We need to install the required packages in your React Native project

yarn add @react-navigation/native@^5.x @react-navigation/stack@^5.x
yarn add react-native-reanimated@2.2.4 react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

If you’re on a Mac and developing for iOS, you need to install the pods (via Cocoapods) to complete the linking.
More details can be found here.

npx pod-install ios

Then we need to add react-native-gesture-handler to the top of your index.js

// index.js

import 'react-native-gesture-handler';
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

Now you need to create 3 files in the root directory.

  • src/navigation/MainNavigator.js
  • src/screens/SplashScreen.js
  • srс/screens/HomeScreen.js

HomeScreen.js

// srс/screens/HomeScreen.js

import React from 'react';
import {View, Text, StyleSheet} from 'react-native';

const HomeScreen = () => {
  return (
    <View style={styles.root}>
      <Text>Home Screen</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  root: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default HomeScreen;

SplashScreen.js

// src/screens/SplashScreen.js
import React, {useRef, useState, useEffect} from 'react';
import {View, StyleSheet, Text} from 'react-native';

const SplashScreen = props => {
  const [authLoaded, setAuthLoaded] = useState(false);

  useEffect(() => {
    setTimeout(() => {
      setAuthLoaded(true);
    }, 5000);
  }, []);

  useEffect(() => {
    if (authLoaded) {
      props.navigation.replace('Home');
    }
  }, [authLoaded, props.navigation]);

  return (
    <View style={styles.root}>
      <Text>Splash Screen</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  root: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default SplashScreen;

MainNavigator.js

// src/navigation/MainNavigator.js
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';

import HomeScreen from '../screens/HomeScreen';
import SplashScreen from '../screens/SplashScreen';

const Stack = createStackNavigator();

const MainNavigator = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Splash">
        <Stack.Screen
          name="Splash"
          options={{animationEnabled: false, header: () => null}}
          component={SplashScreen}
        />
        <Stack.Screen
          name="Home"
          options={{animationEnabled: true, header: () => null}}
          component={HomeScreen}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default MainNavigator;

Now we need to add MainNavigator to App.js and remove the extra code

App.js 

// App.js
import React from 'react';
import {SafeAreaView, StatusBar, useColorScheme} from 'react-native';
import MainNavigator from './src/navigation/MainNavigator';
import {Colors} from 'react-native/Libraries/NewAppScreen';

const App = () => {
  const isDarkMode = useColorScheme() === 'dark';

  const backgroundStyle = {
    backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
    flex: 1,
  };

  return (
    <SafeAreaView style={backgroundStyle}>
      <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
      <MainNavigator />
    </SafeAreaView>
  );
};

export default App;

Let’s run the project in the ios simulator

npx react-native run-ios
Lottie splash screen 1

Perfectly! 

Install and configure lottie-react-native

Because of I am using the react-native version higher 0.60.0
I have to install lottie-react-native (latest) and lottie-ios (3.1.8)
More details can be found here.

yarn add lottie-react-native lottie-ios@3.2.3

IOS

Then go to your ios folder and run:

pod install

If you have issues linking your iOS project like this

Lottie splash screen 2

You need to open ios/AppName.xcodeproj in Xcode
Than right-click on app name in the Project Navigator on the left, and click New File

Lottie splash screen 3

Create a single empty Swift file to the project (make sure that app name target is selected when adding)

Lottie splash screen 4
Lottie splash screen 5

When Xcode asks, press Create Bridging Header and do not remove Swift file then.

Lottie splash screen Create Bridging Header

Now you need re-run your build

ANDROID

You will need to make the following changes:

android/app/src/main/java/<AppName>/MainApplication.java

add import com.airbnb.android.react.lottie.LottiePackage; on the imports section
add packages.add(new LottiePackage()); in List getPackages();

Lottie splash screen MainApplication.java

android/app/build.gradle
add implementation project(‘:lottie-react-native’) to the dependencies block

Lottie splash screen build.gradle

android/settings.gradle

add:

include “:lottie-react-native”
project(“:lottie-react-native”).projectDir = new File(rootProject.projectDir, “../node_modules/lottie-react-native/src/android”)

Lottie splash screen settings.gradle

Finally we have finished setting up the lottie.

Now we need to download any lottie animation from official website

Lottie splash screen lottie website

I have selected this animation

Lottie splash screen animation

Download json animation and add the animation assets to the project

Lottie splash screen animation.json

Now we need to change SplashScreen.js

Add import LottieView from ‘lottie-react-native’; with the other imports

Replace <Text>Splash Screen</Text> with lottieView

<LottieView
    ref={animation => {
        ref.current = animation;
    }}
    style={styles.lottieView}
    source={require('../../assest/splash.json')}
    autoPlay
    loop={false}
    onAnimationFinish={onAnimationFinish}
/>

Add animation state to top of the component

const [animationLoaded, setAnimationLoaded] = useState(false);

Replace useEffect with following code

useEffect(() => {
    if (authLoaded && animationLoaded) {
      props.navigation.replace('Home');
    }
  }, [authLoaded, animationLoaded, props.navigation]);

SplashScreen.js

import React, {useRef, useState} from 'react';
import {View, StyleSheet} from 'react-native';
import LottieView from 'lottie-react-native';
import {useEffect} from 'react';

const SplashScreen = props => {
  const [authLoaded, setAuthLoaded] = useState(false);
  const [animationLoaded, setAnimationLoaded] = useState(false);

  const ref = useRef(null);

  useEffect(() => {
    setTimeout(() => {
      setAuthLoaded(true);
    }, 5000);
  }, []);

  const onAnimationFinish = () => {
    setAnimationLoaded(true);
  };

  useEffect(() => {
    if (authLoaded && animationLoaded) {
      props.navigation.replace('Home');
    }
  }, [authLoaded, animationLoaded, props.navigation]);

  return (
    <View style={styles.root}>
      <LottieView
        ref={animation => {
          ref.current = animation;
        }}
        style={styles.lottieView}
        source={require('../../assest/splash.json')}
        autoPlay
        loop={false}
        onAnimationFinish={onAnimationFinish}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  root: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  lottieView: {
    width: '100%',
  },
});

export default SplashScreen;

Conclusion!

You now should have a simple splash screen at your IOS and Android apps.

Lottie splash screen ios
Lottie splash screen android

Finish!

In my previous article, I explained how to create a React Native app.

Thanks for reading.

This Post Has One Comment

  1. Adarsh Raveendran

    Thanks a lot, I’ve been searching for a fix

Leave a Reply