Building an Alert Modal with React Native
Tags: reactnative, javascript, typescript
Published: 2022-01-26 03:04:06


## Introduction
Modals are one of the most important components when building an application. In this article, you will learn how to build a custom modal component using vanilla React Native and TypeScript. 

This is what we are going to build:

![Modal Component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ds93xqf1x6sm06mc6zbi.png)

## Let's get started!
First of all, you will need to setup your environment following the instructions in the official [React Native documentation](https://reactnative.dev/docs/environment-setup)

To start this new project, I used the [React Native TypeScript template](https://reactnative.dev/docs/typescript)

## The Modal Component

In order to create your new Modal component, you will need to create an interface, since we are using TypeScript

```javascript
interface ModalProps {
  onClose: () => void;
  onOk: () => void;
  visible: boolean;
  title: string;
  description?: string | undefined;
  buttonText?: string | undefined;
}
```
The props onClose, onOk, visible and title are required, but description and buttonText are optional.

Defining the modal function component:

```javascript
function MyModal({
  onClose,
  onOk,
  visible,
  title,
  description,
  // if "buttonText" parameter is not passed, it defaults to 'Ok'
  buttonText = 'Ok',
}: ModalProps) {
  return (
    // passing "visible" variable to manage the Modal visibility
    <Modal animationType="fade" transparent visible={visible}>
      // onClose() function is called when pressing the background
      <TouchableOpacity onPress={() => onClose()} style={styles.container} />
      <View style={styles.modalContainer}>
        // "X" button also calls the onClose() function
        <TouchableOpacity onPress={() => onClose()} style={styles.close}>
          <Text>X</Text>
        </TouchableOpacity>
        <View style={styles.content}>
          // adding image
          <Image
            fadeDuration={0}
            resizeMode="contain"
            style={styles.image}
            source={require('path-to-your-image')}
          />
          <View style={styles.textContainer}>
            <Text style={styles.title}>{title}</Text>
            <Text style={styles.desc}>{description}</Text>
          </View>
        </View>
        // calling onOk() when button is pressed
        <TouchableOpacity onPress={() => onOk()} style={styles.buttonContainer}>
          <Text style={styles.buttonText}>{buttonText}</Text>
        </TouchableOpacity>
      </View>
    </Modal>
  );
}

// styles

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: 'rgba(96,96,96,0.7)',
  },
  modalContainer: {
    flex: 1,
    backgroundColor: '#fff',
    marginHorizontal: 50,
    marginVertical: 100,
    borderRadius: 20,
  },
  content: {
    flex: 0.9,
    alignItems: 'center',
    justifyContent: 'center',
  },
  close: {
    alignItems: 'flex-end',
    width: '100%',
    padding: 10,
  },
  image: {
    width: 150,
    height: 150,
  },
  textContainer: {
    paddingVertical: 20,
    paddingHorizontal: 50,
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  title: {
    fontWeight: 'bold',
    fontSize: 20,
    color: '#000',
    textAlign: 'center',
  },
  desc: {
    fontSize: 14,
    color: '#7a7a7a',
    textAlign: 'center',
  },
  buttonContainer: {
    backgroundColor: '#ff564f',
    borderRadius: 20,
    marginHorizontal: 80,
    padding: 8,
    alignItems: 'center',
  },
  buttonText: {
    color: '#fff',
    textAlign: 'center',
  },
});
```
## Using the modal component
Now, you can use the modal we just created on any screen you want!
In my case, I created a blank screen with a centered "Open Modal" button to show the modal.

```javascript
function App() {
  // hooks which will manage the modal state
  const [toggle, setToggle] = useState(false);

  return (
    <View style={styles.container}>
      // button that changes the state of toggle to show the modal
      <TouchableOpacity onPress={() => setToggle(!toggle)}>
        <Text>Open Modal</Text>
      </TouchableOpacity>
      // verifying if the state of toggle is true
      // if it is, our custom modal component is shown
      {toggle && (
        <Modal
          // passing the parameters which will be used by our modal
          onClose={() => setToggle(!toggle)}
          onOk={() => setToggle(!toggle)}
          title="Have a Promo Code?"
          description="Please login to redeem your promo code"
          buttonText="Login"
          visible={toggle}
        />
      )}
    </View>
  );
}

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

Also, for example purposes, both onOk() and onCancel() functions close the modal.


Tip: although I used a Text component to make the X button, I strongly recommend you to use an icon instead. A very good library for that purpose is [React Native Vector Icons](https://github.com/oblador/react-native-vector-icons)

And it is done! You can view the source code [here](https://github.com/grazieleoliveira/react-native-custom-modal)