How to handle exit app in one screen not in the whole app - React Native?
10,522
Solution 1
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 }
);
}
Solution 2
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
Related videos on Youtube
Author by
DevAS
Updated on June 04, 2022Comments
-
DevAS almost 2 years
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);
-
Hend El-SahliYour issue here could be solved by using a
SwitchNavigator
that would render: 1. Splash screen. 2. Your StackNavigator once you're directed to your stack, the backButton will never take you back to your Splash screen
-
-
DevAS about 5 yearssadly didn't work :/ in every screen I show the Alert
-
DevAS about 5 yearsI write your code just add case "SignIn" alert"something" to test them in the Sign In screen
-
DevAS about 5 yearsI made some magic I don't know why it's work :D i just replace routeName with
this.props.navigation.isFocused()
and it's work finally !! -
DevAS about 5 yearsyes, that's work, If I need to run the alert in the many screens I need to call this function in every screen? for example, I wanna run the alert in SignUp and "Home" and some other!
-
Mukundhan about 5 yearsIf you have specific screens that needs this functionality, you can use it in a common service class and call it on componentDidMount. so that it will be easy to maintain.
-
Oliver D about 4 yearsHow can i handle it in react-navigation V5
-
Zennichimaro over 3 yearsseems like it is no longer the case in v5,
navigation.isFocused()
always returns true and worse isnavigation.canGoBack()
always returns false, I have no idea how to know when I am on top most of the stack and really can't go back anymore -
Mukundhan over 3 yearshave you tried using a counter redux action, we have used global counter before finding this solution. it will always work!
-
Joshua Pinter over 2 years@Zennichimaro I'm on version 5 and from my tests,
navigation.canGoBack()
is working well. It showsfalse
when you're at the root of the stack and showstrue
when I'm nested down at least 1 screen in the stack. Not sure how your finding this or maybe they've updated it since you tried it. I'm on"@react-navigation/native": "5.9.8", "@react-navigation/stack": "5.14.9"