Reputation: 885
I am using https://wix.github.io/react-native-navigation/docs/before-you-start/ for navigation for my react native app. I have one issue where let say there are three cmp A,B,C. From comp A there is a history.push() executed which redirect to cmp B and then cmp B is some path matcher where renders particular component based on the path pushed from A, let say cmp B matches the path and than it renders C cmp, where C has smth like this:
Code:
Navigation.push(componentId, {
component: {
id: 'BottomSheetRollupView',
name: 'bottomSheet.Rollup',
passProps: {
component,
passProps,
},
options: {
statusBar: {
style: Platform.select({android: 'light', ios: 'dark'}),
},
},
},
});
So the C cmp pushes a new screen to the stack, so at this moment when clicking back from the navigation I would like to instead redirect me to A and not B. How can I change the behaviour of back button or can I disable it somehow? pressing back button redirects me back to cmp B currently and I dont want to!
Thank you.
Upvotes: 1
Views: 1329
Reputation: 7315
You can change the behavior when going back by using navigation.addListener()
. I found it a little clunky but it works - in our case we warn on going back if data would be lost. We also had to distinguish between Save and Back presses, which we did by setting a state flag when Save button was pressed. Here's what the hook looks like - I think it should be adaptable to your needs:
// 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: () => {} },
]);
}
Upvotes: 1