I am trying to Make the go back swipe go to different screen
I have the following order of screens MenuScreen
, CartScreen
then PaymentScreen
.
so for example if the user in the PaymentScreen
and swipe back user should go back to the CartScreen
but I wanna navigate the user to the MenuScreen
NOT TO CartScreen
useEffect(() => {
navigation.addListener('beforeRemove', e => {
e.preventDefault();
navigation.navigate('MenuScreen');
});
}, [navigation]);
but I am facing this error:
ERROR RangeError: Maximum call stack size exceeded.
any clue how to solve this problem? or maybe solution?
CodePudding user response:
There are two ways Ahmed, how you can achieve this. Following are the pointers:
- StackActions Reference [PREFFERED]: Now you can read more about this from the link itself, but precisely, you can use if the navigation is not that complex as it looks as per your question Ahmed. So the task is,
first moving from Menu -> Cart -> Payment
and then when going backPayment -> Menu
. To do that using this, you simply have to useStackAction
usingnavigation
:
import { StackActions } from '@react-navigation/native';
// While going from Menu -> Cart
navigation.navigate('Cart');
// While going from Cart -> Payment (Here is the key)
navigation.dispatch(
StackActions.replace('Payment')
);
Now when you just swipe back, you will see the Menu Page only.
What did we do: We replaced the Cart
from the navigation stack, so only pages which were available were, Menu and Payment in the stack. Resulting in going back to Menu. Do not forget to use navigation.navigate() to go to
Cart`. It will help you.
- CommonActions Reference [NOT SO PREFERRED]: Now this will completely reset the navigation as per your will, and help you achieve what you want to achieve. Here you don't have to actually worry about what do you use while navigating from
Menu -> Cart
, but we do have to worry about going fromCart -> Payment
.
Disadvantage: While using this, you will lose all the progress you have made in the Menu
page, which you want to see while coming back from Payment -> Menu
using Swipe
, Android Hard Back button
. Also, it will reset the whole navigation stack, so you are creating a new stack with your means. Hence, not so preferred
import { CommonActions } from '@react-navigation/native';
// from Menu -> Cart
navigation.navigate('Cart');
// From Cart -> Payment (Most important) -> Resetting the whole stack
navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'Menu' },
{ name: 'Payment' },
]
})
);
CodePudding user response:
Remove navigation from useEffect deps and add a cleanup function
The reason Maximum call stack size exceeded
occurs is because you have navigation
in your deps array in the useEffect call. This means every time the navigation option changes, it will add a new listener, resulting in the error.
Additionally, you should also add a cleanup function to your effect so the listener does not cause unwanted behavior on other pages.
Here is how I would refactor the effect:
useEffect(() => {
// create reference to the listener so it can be cleaned up
const unsubscribe = navigation.addListener('beforeRemove', e => {
e.preventDefault();
navigation.navigate('MenuScreen');
});
// clean up the listener on unmount
return unsubscribe;
}, []); // remove navigation from deps
CodePudding user response:
Use navigation.reset
or navigation.popToTop()
useEffect(() => navigation.addListener('beforeRemove', e => {
e.preventDefault();
navigation.popToTop();
});
, [navigation]);