BackHandler 的 HardwareBackPress 事件在导航器的每个屏幕上触发

Inf*_*rus 3 react-native react-navigation

BackHandler在应用程序的“主”屏幕上使用来提醒用户确认退出应用程序。我的根导航器上有 2 组屏幕身份验证和主页,并且isLoggedbool 确定显示哪一组。

问题:应用程序的第一次渲染工作正常(无论是身份验证还是主屏幕集),但是当isLogged更改并且屏幕集发生变化时,BackHandler开始在更改集的每个屏幕上触发。这仅在重新启动应用程序后才能修复。工作示例 - https://snack.expo.dev/@msaxena92/11fd51

预期结果:在导航器内按回键应该会将您带到initialRoute导航器的第一个屏幕或第一个屏幕,只有在此之后,当导航堆栈中没有更多屏幕时,它才会退出应用程序。

sat*_*164 6

您有 2 个选择:

使用useFocusEffect钩子而不是钩子useEffect将确保仅当您在此屏幕上时才运行效果:

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();
  }, [])
);
Run Code Online (Sandbox Code Playgroud)

或者,您还可以检查效果内的焦点:

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]);
Run Code Online (Sandbox Code Playgroud)

另请参阅https://reactnavigation.org/docs/custom-android-back-button-handling/