0

我想要实现的目标很简单。我希望用户被迫确认退出名为“结帐”的选项卡导航器。

我在 React Navigation 文档上阅读了有关防止返回“beforeRemove”事件的信息,该事件看起来很整洁且使用正确。

问题是,在他们的示例中,他们在事件侦听器中调用 Alert,而我想显示一个带有是和否按钮的自定义模式。

这是 React Navigations 示例代码:

function EditText({ navigation }) {
  const [text, setText] = React.useState('');
  const hasUnsavedChanges = Boolean(text);

  React.useEffect(
    () =>
      navigation.addListener('beforeRemove', (e) => {
        if (!hasUnsavedChanges) {
          // If we don't have unsaved changes, then we don't need to do anything
          return;
        }

        // Prevent default behavior of leaving the screen
        e.preventDefault();

        // Prompt the user before leaving the screen
        Alert.alert(
          'Discard changes?',
          'You have unsaved changes. Are you sure to discard them and leave the screen?',
          [
            { text: "Don't leave", style: 'cancel', onPress: () => {} },
            {
              text: 'Discard',
              style: 'destructive',
              // If the user confirmed, then we dispatch the action we blocked earlier
              // This will continue the action that had triggered the removal of the screen
              onPress: () => navigation.dispatch(e.data.action),
            },
          ]
        );
      }),
    [navigation, hasUnsavedChanges]
  );

  return (
    <TextInput
      value={text}
      placeholder="Type something…&quot;
      onChangeText={setText}
    />
  );
}

这是我尝试过的代码:

useEffect(() => {
    navigation.addListener('beforeRemove', e => {
      if (userConfirmedExit) {
        navigation.dispatch(e.data.action);
      } else {
        e.preventDefault();
        setShowExitModal(true);
      }
    });
  }, [navigation, userConfirmedExit]);

  const handleConfirmExit = () => {
    setUserConfirmedExit(true);
    navigation.replace('ProfileTab');
  };

  const handleDeclineExit = () => setShowExitModal(false);

我必须在 eventListener 中使用 navigation.dispatch(e.data.action) 但 handleConfirmExit 函数必须在它之外,我只是不知道如何使用 beforeRemove 侦听器并从我的位置显示自定义模式可以退出选项卡。

按下后退按钮时侦听器正在触发并且模式显示,但是当按下是时没有任何反应(即运行 handleConfirmExit 函数)。

我尝试从 useEffect 中删除依赖项。确实有效的一件事,但仅在 Android 上是这样的:

useEffect(() => {
    navigation.addListener('beforeRemove', e => {
      e.preventDefault();
      setShowExitModal(true);
    });
  }, [navigation]);

  const handleConfirmExit = () => {
    navigation.removeListener('beforeRemove', () => {});
    navigation.replace('ProfileTab');
  };

  const handleDeclineExit = () => setShowExitModal(false);

在 iOS 上,由于某种原因,模式停留在下一个屏幕上,我认为罪魁祸首是上一个示例中“beforeRemove”侦听器的错误实现。

谢谢!

4

1 回答 1

0

使用 BackHandler ,您可以使用 navigation.goBack() 而不是 BackHandler.exitApp()

import { BackHandler} from "react-native";
const backAction = () => {
  Alert.alert("Discard changes?", "Are you sure you want to exit?", [
    {
      text: "NO",
      onPress: () => null,
      style: "cancel"
    },
    { text: "YES", onPress: () => BackHandler.exitApp() }
  ]);
  return true;
};

useEffect(() => {
  BackHandler.addEventListener("hardwareBackPress", backAction);
return () => {
  BackHandler.removeEventListener("hardwareBackPress", backAction);
}   
}, []);
于 2022-02-18T12:55:10.797 回答