如何在反应本机导航时覆盖后退按钮的行为
how to override behaviour of backButton on react native navigation
我正在使用 https://wix.github.io/react-native-navigation/docs/before-you-start/ 为我的 React 本机应用程序导航。我有一个问题,假设有三个 cmp A、B、C。从 comp A 执行 history.push() 重定向到 cmp B 然后 cmp B 是一些路径匹配器,其中根据从 A 推送的路径渲染特定组件,假设 cmp B 匹配路径并且比它渲染C cmp,其中 C 有这样的东西:
代码:
Navigation.push(componentId, {
component: {
id: 'BottomSheetRollupView',
name: 'bottomSheet.Rollup',
passProps: {
component,
passProps,
},
options: {
statusBar: {
style: Platform.select({android: 'light', ios: 'dark'}),
},
},
},
});
所以 C cmp 将一个新屏幕推送到堆栈,所以此刻当从导航中单击返回时,我想改为将我重定向到 A 而不是 B。如何更改后退按钮的行为或我可以以某种方式禁用它吗?按后退按钮会将我重定向回 cmp B,我不想!
谢谢。
您可以使用 navigation.addListener()
更改返回时的行为。我发现它有点笨拙,但它确实有效——在我们的例子中,如果数据丢失,我们会警告返回。我们还必须区分 Save 和 Back 按下,这是通过在按下 Save 按钮时设置状态标志来实现的。挂钩的外观如下 - 我认为它应该可以适应您的需求:
// Based on: https://reactnavigation.org/docs/preventing-going-back/
function useAlertOnGoBack({
hasEdited,
didSave,
}: {
hasEdited: boolean;
didSave: boolean;
}) {
const navigation = useNavigation();
useEffect(() => {
const unsubscribe = navigation.addListener("beforeRemove", e => {
if (!hasEdited || didSave) {
// No listener
return;
}
// Prevent default behavior of leaving the screen
e.preventDefault();
showExitWithoutSavingAlert(() => navigation.dispatch(e.data.action));
});
return unsubscribe;
}, [hasEdited, navigation, didSave]);
}
export function showExitWithoutSavingAlert(dismissScreen: () => void) {
// Prompt the user before leaving the screen
Alert.alert("Discard unsaved changes?", undefined, [
{
text: "Discard Changes",
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: dismissScreen,
},
{ text: "Cancel", style: "cancel", onPress: () => {} },
]);
}
我正在使用 https://wix.github.io/react-native-navigation/docs/before-you-start/ 为我的 React 本机应用程序导航。我有一个问题,假设有三个 cmp A、B、C。从 comp A 执行 history.push() 重定向到 cmp B 然后 cmp B 是一些路径匹配器,其中根据从 A 推送的路径渲染特定组件,假设 cmp B 匹配路径并且比它渲染C cmp,其中 C 有这样的东西:
代码:
Navigation.push(componentId, {
component: {
id: 'BottomSheetRollupView',
name: 'bottomSheet.Rollup',
passProps: {
component,
passProps,
},
options: {
statusBar: {
style: Platform.select({android: 'light', ios: 'dark'}),
},
},
},
});
所以 C cmp 将一个新屏幕推送到堆栈,所以此刻当从导航中单击返回时,我想改为将我重定向到 A 而不是 B。如何更改后退按钮的行为或我可以以某种方式禁用它吗?按后退按钮会将我重定向回 cmp B,我不想!
谢谢。
您可以使用 navigation.addListener()
更改返回时的行为。我发现它有点笨拙,但它确实有效——在我们的例子中,如果数据丢失,我们会警告返回。我们还必须区分 Save 和 Back 按下,这是通过在按下 Save 按钮时设置状态标志来实现的。挂钩的外观如下 - 我认为它应该可以适应您的需求:
// Based on: https://reactnavigation.org/docs/preventing-going-back/
function useAlertOnGoBack({
hasEdited,
didSave,
}: {
hasEdited: boolean;
didSave: boolean;
}) {
const navigation = useNavigation();
useEffect(() => {
const unsubscribe = navigation.addListener("beforeRemove", e => {
if (!hasEdited || didSave) {
// No listener
return;
}
// Prevent default behavior of leaving the screen
e.preventDefault();
showExitWithoutSavingAlert(() => navigation.dispatch(e.data.action));
});
return unsubscribe;
}, [hasEdited, navigation, didSave]);
}
export function showExitWithoutSavingAlert(dismissScreen: () => void) {
// Prompt the user before leaving the screen
Alert.alert("Discard unsaved changes?", undefined, [
{
text: "Discard Changes",
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: dismissScreen,
},
{ text: "Cancel", style: "cancel", onPress: () => {} },
]);
}