How can I prevent hardware back button for specific screen with React Native?

Viewed 180

In the application I made with React Native, the screens are opened as follows. User registers on SignUp screen. I want to prevent it from going backwards on the A screen with the phone back button. If I do it in the first way (you can see it in the code written for page B below), I get what I want and it only gives a warning when the back button is pressed on the A screen. But in this way, when the user log out on the C screen, it gives the same warning when switching to the Launch screen. I don't understand how this happens. If I do it the second way, it gives this warning when I press the back button on all screens. Please, all I want is for it to only warn when pressing the back button from the A screen. How can I do that?

Launch screen --> SignUp screen --> A screen --> B screen --> C screen

Launch

import React, { useEffect } from "react"
import { View } from "react-native"
import { useSelector } from "react-redux"
import { loginSelector } from "../../redux/LoginRedux"


const Launch = ({ navigation }) => {

  const isLoggedIn = useSelector(loginSelector)

  useEffect(() => {
    if (!isLoggedIn) {
      navigation.navigate("SignUp")
    } else {
      navigation.navigate("D-Screen")
    }
  }, [])

  return (
    <View/>
  )
}

export default Launch

B Screen

// First way (It only works on the b screen, but when the user logs out, it gives this warning when the Launch screen is opened.)
  
  useEffect(() =>
    navigation.addListener('beforeRemove', (e) => {
      e.preventDefault();
      Alert.alert(
        "Warning,
        "Do you want to exit",
        [
          { text: "No", onPress: () => null },
          { text: "Yes", onPress: () => BackHandler.exitApp() }
        ],
        { cancelable: true }
      );
    }), [])
    
 
 /* Second way (it works on all screens not just b screen)*/
 
   useEffect(() => {
    const backAction = () => {
      Alert.alert("Hold on!", "Are you sure you want to go back?", [
        {
          text: "Cancel",
          onPress: () => null,
          style: "cancel"
        },
        { text: "YES", onPress: () => BackHandler.exitApp() }
      ]);
      return true;
    };

    const backHandler = BackHandler.addEventListener(
      "hardwareBackPress",
      backAction
    );

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

D Screen

//

  const logOut = () => {
    dispatch(setLoginStatus(false));
    navigation.reset({
      index: 0,
      routes: [{ name: 'Launch' }]
    })
  };

//

Navigation

const Stack = createStackNavigator();

const StackNavigator = () => {
  return (
    <Stack.Navigator
      initialRouteName={"Launch"}
      screenOptions={{headerShown: false, animationEnabled: false}}>
      <Stack.Screen name={Launch} component={"Launch"} />
      <Stack.Screen name={SignUp} component={"SignUp"} />
      <Stack.Screen name={AScreen} component={"A"} />
      <Stack.Screen name={BScreen} component={"B"} />
    </Stack.Navigator>
  );
};

1 Answers

I think that it can work: You can use navigation.isFocused() to check if user is in A screen

const backAction = () => {
  if (navigation.isFocused()) {
    Alert.alert("Hold on!", "Are you sure you want to go back?", [
      {
        text: "Cancel",
        onPress: () => null,
        style: "cancel"
      },
      { text: "YES", onPress: () => BackHandler.exitApp() }
    ]);
    return true;
  }
};

const backHandler = BackHandler.addEventListener(
  "hardwareBackPress",
  backAction
);
Related