Home > OS >  RN: Swipe Back to different Screen
RN: Swipe Back to different Screen

Time:09-17

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 back Payment -> Menu. To do that using this, you simply have to use StackAction using navigation:
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 from Cart -> 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]);
  • Related