Creating a Modal to display an alert in another screen with React Native

Using functional components and Expo!

Modals are a great way to display alerts to grab a user’s attention to provide information in the simplest form. These components are commonly used throughout both Web & Mobile. In this article, I will show you a way to use Modals to display alerts in another screen after some sort of trigger (i.e. a button tap).

Setting up Expo

We are going to use Expo since it’s going to help us build our mobile app. If you are unfamiliar with Expo, check this link out. Open up your terminal, run the expo command to create a new React Native project.

Once you have configured everything, we are going to install a few frameworks before we get everything set up. On your terminal, run the following commands:

yarn add react-navigation react-navigation-stack @react-native-community/masked-view expo react-native-gesture-handler react-native-reanimated react-native-screens

If by any chance you need more info on React Navigation V4, check out the documentation here.

Setting up our folder structure

Cool! Let’s quickly setup the folder and add files to it.

How we are setting up our folders with its files

Navigation Setup

First things first, we will setup our Navigator in our App.js file. It will look something like this:

import React from 'react';
import Navigator from './navigation/Navigator';
import { enableScreens } from 'react-native-screens';
// using this will will optimize usage and performance
enableScreens();
export default function App() {
return (
<Navigator />
);
};

Next we will configure the actual navigation in the Navigator.js file. This is where we will use the Stack Navigator and add the screens to the stack.

import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import MainScreen from '../screens/MainScreen';
import SecondScreen from '../screens/SecondScreen';
const MainStackNavigator = createStackNavigator({
Main: {
screen: MainScreen,
navigationOptions: () => ({
title: 'Main Screen'
})
},
Second: {
screen: SecondScreen,
navigationOptions: () => ({
title: 'Second Screen'
})
}
});
export default createAppContainer(MainStackNavigator);

Setting up our Screens

Setting up our screens is fairly simple. We are only creating a view with a button component. Since it’s a very simple app, we are only creating two screens: Main.js and SecondScreen.js (name it whatever you want).

// MainScreen.jsimport React from 'react';
import { View, StyleSheet, Button } from 'react-native';
const MainScreen = props => {
return(
<View style={styles.container}>
<Button
color='white'
title='Go to second screen'
onPress={ () => props.navigation.navigate('Second')}/>
</View>
)
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
alignItems: 'center', justifyContent: 'center'
}
});
export default MainScreen;

And the code for the SecondScreen.js:

// SecondScreen.jsimport React from 'react';
import { View, StyleSheet, Button } from 'react-native';

const SecondScreen = props => {
return (
<View style={styles.container}>
<Button color='white'
title='Show Modal on Main Screen'
onPress={ () => props.navigation.navigate('Main')} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
alignItems: 'center', justifyContent: 'center'
}
});
export default SecondScreen;

Now that we have our screens all set up, here is what it looks like:

Customizing our Modal Component

We are ready to customize our Modal! First we can create a folder where we can store our custom components. To do so, create a new folder called “components” then create a file within that folder, for now we can call it “CustomModal” (name it to whatever of your liking), and type in the following code:

// CustomModal.jsimport React from 'react';
import { Modal, StyleSheet, Text, View} from 'react-native';
const CustomModal = ({ title, isVisible }) => {return (<View style={styles.modalContainer}>
<Modal animationType='fade' transparent={true} visible {isVisible}>
<View style={styles.modalContainer}>
<View style={styles.modalView}>
<Text style={styles.textStyle}>{title}</Text>
</View>
</View>
</Modal>
</View>
);
};
const styles = StyleSheet.create({ modalContainer: {
alignItems: 'center',
position: 'absolute',
height: '100%', width: '100%',
},
modalView: {
flexDirection: 'row',
justifyContent: 'flex-start', alignItems: 'center',
top: 100,
width: '85%', height: 50,
backgroundColor: 'black',
borderRadius: 8
},
textStyle: {
color: 'white',
textAlign: 'center',
fontSize: 24,
marginLeft: 20
}
});
export default CustomModal;

The Modal props that we, that we should be focusing on are: animationType, transparent, and visible.

  • AnimationType: There are only three options for the animation type. They are: ‘none’, ‘slide’, & ‘fade’
  • Transparent: This will show the background of the Modal. For now, we want to set it to “true” so we don’t see it and only focus on the custom view we are creating.
  • Visible: This property is key. Using the useState hook, we can have the modal to appear and disappear to our liking

Alright, we configured our custom Modal. Let’s import it in our MainScreen.js file and use it.

We also need to add the useState hook to keep track of the Modal’s state. For now, let’s set it to “true”.

// MainScreen.jsimport React, {useState} from 'react';
import { View, StyleSheet, Button } from 'react-native';
import CustomModal from '../components/CustomModal';const MainScreen = props => {const [isModalVisible, setModalVisible] = useState(true); return(
<View style={styles.container}>
<CustomModal title='Success!' isVisible {isModalVisible}/>
<Button
color='white'
title='Go to second screen'
onPress={ () => props.navigation.navigate('Second')}/>
</View>
)
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
alignItems: 'center', justifyContent: 'center'
}
});
export default MainScreen;

Now. It’s going to look like this:

Our custom modal is now at the top of the screen!

Showing the Modal then dismissing it automatically

For now we have the Modal displaying in the main screen. The final task is to have the Modal appear when the user presses the button from the second screen. To do so, we need to pass parameters from the second screen to the main.

// SecondScreen.jsimport React from 'react';
import { View, StyleSheet, Button } from 'react-native';
const SecondScreen = props => {const showModalToMainScreen = () => {
props.navigation.navigate('Main', { showModal: true })
}
return (
<View style={styles.container}>
<Button color='white'
title='Show Modal on Main Screen'
onPress={ () => showModalToMainScreen() />
</View>
);
};
* rest of code remains the same *

And now that we pass the param showModal, we will use a listener whenever the user sees the main screen and checks if showModal is true or not. To do so:

// MainScreen.jsimport React, {useState, useEffect } from 'react';
import { View, StyleSheet, Button } from 'react-native';
import CustomModal from '../components/CustomModal';
const MainScreen = props => {const [isModalVisible, setModalVisible] = useState(true);useEffect( () => { const listener = props.navigation.addListener('didFocus', () => { if (props.navigation.getParam('showModal')) {
toggleModal();
props.navigation.setParams({ showModal: false });
}
});
return () => {
listener.remove();
};
}, [props.navigation.getParam('showModal')]);const toggleModal = () => {
setModalVisible(true);
setTimeout( () => {
setModalVisible(false);
}, 3000)
};
* rest of code remains the same *
  • Recall that the useEffect hook will let React know that your component needs to re-render. Using this hook will display our Modals fluidly.
  • using a listener will help us detect when the screen is shown. Specifically, we are looking for a param called showModal from SecondScreen.js
  • toggleModal() is a function where we set the visibility of the Modal to be true and then after 3 seconds (hence: 3000), we will set the state of the modal to false (hence: setModalVisible(false) )
  • After the function finishes its execution, we will set the param showModal to avoid a loop. Lastly, we will return where we will “unsubscribe” from the listener (in other words, remove the listener)
  • Inside the useEffect param, we would only call the useEffect block only when there is a change within the showModal param. That way, this useEffect won’t be re-rendering a lot

The result:

Ayeeee! The Modal fades in and out!

Bonus: Adding a Lottie Animation

Although we have the Modal to display, personally I love using Lottie files to display animations. I am not going into too much detail, but I can definitely provide code where you can play around with it. Follow the github repo here and install the framework in your project!

Happy Holidays!

Thank you for reading! Hope you guys enjoy your holidays with your loved ones!

Down to earth & passionate iOS Engineer