Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle exit app in one screen not in the whole app - React Native?

I have some issue with BackHandler, the issue is

when running the app and go to the let's say Sign Up screen and touch the back in my mobile they will run the function and show the Alert to confirm, but now when I go to any other screen and touch the back they will I need to just back to the previous screen on every back BackHandler.exitApp(); runs, Although I write if the routname is SignUp just exit the app not other screens

this is my code

Sign Up

    import React from "react";
    import {
      Text,
      TextInput,
      ActivityIndicator,
      View,
      KeyboardAvoidingView,
      ScrollView,
      Image,
      TouchableOpacity,
      BackHandler,
      Alert
    } from "react-native";
    export default class signUp extends React.Component {
      constructor(props) {
        super(props);

      }

      componentDidMount() {
        BackHandler.addEventListener("hardwareBackPress", this.backPressed);
      }

      componentWillUnmount() {
        BackHandler.removeEventListener("hardwareBackPress", this.backPressed);
      }
      backPressed = () => {
    let { routeName } = this.props.navigation.state;
    console.log("route is :  " + routeName);

    if (routeName == "SignUp") {
      console.log("ROUTE :  " + routeName);
      Alert.alert(
        "Exit App",
        "Do you want to exit?",
        [
          {
            text: "No",
            onPress: () => console.log("Cancel Pressed"),
            style: "cancel"
          },
          { text: "Yes", onPress: () => BackHandler.exitApp() }
        ],
        { cancelable: false }
      );
      return true;
    } else {
      return false;
    }
  };

      render() {....}
    }

Routes

import { createStackNavigator, createAppContainer } from "react-navigation";
import React from "react";
import { View } from "react-native";
import Splash from "../screens/Splash";
import Home from "../screens/Home";
import SignUp from "../screens/SignUp";
import SignIn from "../screens/SignIn";
import ForgetPassword from "../screens/ForgetPassword";

const Routes = createStackNavigator(
  {
    Splash: {
      screen: Splash,
      navigationOptions: {
        header: null
      }
    },
    SignUp: {
      screen: SignUp,
      navigationOptions: () => ({
        // header: null
        title: "Sign Up",
        headerLeft: null,
        headerTintColor: "#fc0301",
        headerStyle: {
          borderBottomColor: "white"
        },
        headerTitleStyle: {
          color: "#fc0301",
          textAlign: "center",
          flex: 1,
          elevation: 0,
          fontSize: 25,
          justifyContent: "center"
        }
      })
    },
    SignIn: {
      screen: SignIn,
      navigationOptions: {
        title: "Sign In",
        headerRight: <View />,
        headerTintColor: "#fc0301",
        headerStyle: {
          borderBottomColor: "white"
        },
        headerTitleStyle: {
          color: "#fc0301",
          textAlign: "center",
          flex: 1,
          elevation: 0,
          fontSize: 25,
          justifyContent: "center"
        }
      }
    },
    ForgetPassword: {
      screen: ForgetPassword,
      navigationOptions: {
        header: null
      }
    },
    Home: {
      screen: Home,
      navigationOptions: {
        header: null
      }
    }
  },
  {
    initialRouteName: "Splash"
  }
);

export default createAppContainer(Routes);
like image 281
DevAS Avatar asked Mar 22 '19 19:03

DevAS


2 Answers

You can check for the screen has been focused prior to call the alert instead of checking the routeName from navigation.

the updated code might look like this.

if (this.props.navigation.isFocused()) {
    Alert.alert(
    "Exit App",
    "Do you want to exit?",
    [
      {
        text: "No",
        onPress: () => console.log("Cancel Pressed"),
        style: "cancel"
      },
      { text: "Yes", onPress: () => BackHandler.exitApp() }
    ],
    { cancelable: false }
    );
}
like image 161
Mukundhan Avatar answered Sep 23 '22 12:09

Mukundhan


Version 5+, try using navigation.canGoBack().

I discovered this from Zennichimaro's comment.

If there's only one screen in your stack.

navigation.canGoBack() //=> false

If there's at least one screen below you in the stack.

i.e. If there's a screen that you can go "back" to.

navigation.canGoBack() //=> false

navigation.navigate( "screen2" );

navigation.canGoBack() //=> true

navigation.goBack();

navigation.canGoBack() //=> false
like image 29
Joshua Pinter Avatar answered Sep 25 '22 12:09

Joshua Pinter