我想要实现的目标很简单。我希望用户被迫确认退出名为“结帐”的选项卡导航器。
我在 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…"
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”侦听器的错误实现。
谢谢!