Home > Software design >  BackHandler's HardwareBackPress event gets triggered on every screen of the navigator
BackHandler's HardwareBackPress event gets triggered on every screen of the navigator

Time:05-06

I'm using BackHandler on the "home" screen of my app to alert confirmation to the user to exit the app. I've 2 sets of screen Authentication and Home on my root navigator and isLogged bool determines which set gets shown.

Problem: The first render of the app works fine(be it Auth or Home set of screens) but when isLogged is changed and the set of screens changes, BackHandler starts triggering on every screen of the changed set. This is only fixed after restarting the app. Working example - https://snack.expo.dev/@msaxena92/11fd51

Expected result: Pressing back inside a navigator should take you to the initialRoute or first screen of the navigator and only after that when there are no more screens in the navigation stack it exits the app.

CodePudding user response:

You have 2 options:

Use the useFocusEffect hook instead of useEffect which will make sure that the effect is run only when you're on this screen:

useFocusEffect(
  React.useCallback(() => {
    const backAction = () => {
      Alert.alert("Hold on!", "Are you sure you want to exit?", [
        { text: "Cancel" },
        { text: "Yes", onPress: () => BackHandler.exitApp() }
      ]);
      return true;
    };

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

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

Alternatively, you can also check for focus inside the effect:

React.useEffect(() => {
  const backAction = () => {
    if (!navigation.isFocused()) {
      return false;
    }

    Alert.alert("Hold on!", "Are you sure you want to exit?", [
      { text: "Cancel" },
      { text: "Yes", onPress: () => BackHandler.exitApp() }
    ]);
    return true;
  };

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

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

Also see https://reactnavigation.org/docs/custom-android-back-button-handling/

  • Related