skip to Main Content

I’m facing a challenge where I want to display an Alert when users press the back button on the device within a Modal in my React Native application. The desired behavior is to show an Alert with the message "You have turned off the modal using the device’s back button", and then close the modal. Below is my source code:

import {
  View,
  Text,
  Modal,
  StyleSheet,
  Button,
  Alert,
  BackHandler,
  TouchableOpacity,
} from 'react-native';
import React, {useState, useEffect} from 'react';

const Lab3_3 = () => {
   const [modalVisible, setModalVisible] = useState(false);
   useEffect(() => {
     const handleBackPress = () => {
       if (modalVisible) {
         Alert.alert(
           'Alert',
           'You have turned off the modal using the devices back button',
           [{text: 'OK', onPress: () => setModalVisible(false)}],
         );
         return true; 
       }
       return false; 
     };

     const backHandler = BackHandler.addEventListener(
       'hardwareBackPress',
       handleBackPress,
     );

     return () => {
       backHandler.remove();
     };
   }, [modalVisible]);



  return (
    <View>
      <Modal
        animationType="slide"
        transparent={true}
        visible={modalVisible}
        onRequestClose={() => setModalVisible(false)}>
        <View style={styles.centeredView}>
          <View style={styles.modalView}>
            <Text>Hello world!</Text>
            <Button title="Close Modal" onPress={() => setModalVisible(false)} />
          </View>
        </View>
      </Modal>

      <TouchableOpacity
        style={styles.customButton}
        onPress={() => setModalVisible(true)}>
        <Text style={styles.buttonText}>Open Modal</Text>
      </TouchableOpacity>
    </View>
  );
};

const styles = StyleSheet.create({
  customButton: {
    width: '100%',
    height: '100%',
    justifyContent: 'center',
    alignItems: 'center',
  },
  buttonText: {
    color: 'white',
    fontWeight: 'bold',
    padding: 10,
    backgroundColor: 'green',
    borderRadius: 5,
  },
  centeredView: {
    width: '100%',
    height: '100%',
    justifyContent: 'center',
    alignItems: 'center',
    marginTop: 22,
  },
  modalView: {
    backgroundColor: 'white',
    borderRadius: 20,
    padding: 20,
    alignItems: 'center',
    elevation: 5,
  },
});

export default Lab3_3;

I’m looking for suggestions or solutions to ensure that the desired Alert behavior is achieved. Thank you!

2

Answers


  1. If you look at the docs for onRequestClose

    Because of this required prop, be aware that BackHandler events will not be emitted as long as the modal is open.

    And in the Backhandler docs

    Warning for modal users: If your app shows an opened Modal, BackHandler will not publish any events (see Modal docs).

    So you’re event listener is not getting triggered. But this is the default rule. You’d have to use something other than a modal, (i.e. a view that has animations, etc.) for your desired behavior.

    Sorry!

    Login or Signup to reply.
  2. As per React Native documents "BackHandler events will not be emitted as long as the modal is open"

    You need to put your logic inside onRequestClose callBack.

    Something like:

        <Modal
          // ... otherProps
          onRequestClose={() =>
            Alert.alert(
              "Alert",
              "You have turned off the modal using the devices back button",
              [{ text: "OK", onPress: () => setModalVisible(false) }]
            )
          }
        />
    
    // ...rest

    Alternatively:

        <Modal
          // ... otherProps
          onRequestClose={() =>
            Platform.OS === "android"
              ? Alert.alert(
                  "Alert",
                  "You have turned off the modal using the devices back button",
                  [{ text: "OK", onPress: () => setModalVisible(false) }]
                )
              : setModalVisible(false)
          }
        />
    
    // ...rest
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search