React Navigation: Navigate Back To Root using NavigationActions.reset, goBack and getStateForAction

前端 未结 7 665
灰色年华
灰色年华 2020-12-28 15:05

Say I\'ve navigated through 4 screens in my StackNavigator App and now I want to go back to the first screen. There seems to be three different ways to do this and they do n

相关标签:
7条回答
  • 2020-12-28 15:45

    Also spent some time on this, let me sum up what I discovered, there are multiple solutions/workarounds for this:

    1) Use CardStackStyleInterpolator

    The pull request mentioned by Cristiano Santos seems to be merged. So you can load the CardStackStyleInterpolator with this import:

    import CardStackStyleInterpolator from 'react-navigation/src/views/CardStack/CardStackStyleInterpolator'
    

    To apply it like this:

    const YourStackNavigator = StackNavigator({
        Screen1: { screen: Screen1 },
        Screen2: { screen: Screen2 },
    }, {
        transitionConfig: () => ({
            screenInterpolator: (props) => CardStackStyleInterpolator.forHorizontal(props)
        })
    });
    

    In my case, I just jump to the next screen like:

    this.props.navigation.navigate('Modal_AddGoodClass');
    

    But in my reducer, I reset the navigator when the Modal_AddGoodClass screen is triggered:

    const NewExportReceiptNavigationReducer = (state, action) => {
        // Default stuff
    
        let newStateBuffer = newState || state;
    
        if (action) {
            if (action.type === 'Navigation/NAVIGATE') {
                if (action.routeName === 'Modal_AddGoodClass') {
                    newStateBuffer = {
                        index:  0,
                        routes: [
                            newStateBuffer.routes[newStateBuffer.routes.length - 1]
                        ]
                    };
                }
            }
        }
    
        return newStateBuffer;
    };
    
    module.exports = NewExportReceiptNavigationReducer;
    

    This works pretty well, except the fact, that still a "back" animation is used instead of a "forward" one.

    You can also find here some example code that uses CardStackStyleInterpolator.

    2) Overwrite getStateForAction:

    As Fendrian mentioned here you can overwrite getStateForAction of your router to avoid the navigator to go back. This seems to work except for the "swipe back" gesture on iOS:

    Nav = StackNavigator(navScreens, navOptions);
    const defaultGetStateForAction = Nav.router.getStateForAction;
    Nav.router.getStateForAction = (action, state) => {
      if (
        state &&
        action.type === NavigationActions.BACK &&
        (
          state.routes[state.index].routeName === 'Login' ||
          state.routes[state.index].routeName === 'Main'
        )
      ) {
        // Returning null indicates stack end, and triggers exit
        return null;
      }
      return defaultGetStateForAction(action, state);
    };
    

    nov-05-2017 11-34-07

    0 讨论(0)
  • 2020-12-28 15:50

    react-native navigation has popToTop we can use it like blow

    this.props.navigation.popToTop()
    
    0 讨论(0)
  • 2020-12-28 15:50

    You can do this by using the popToTop method from the Navigation prop. Also, if you are using redux, you should update your Redux integration.

    Hope this helps!

    0 讨论(0)
  • 2020-12-28 15:54

    Here's a quick fix. This will remove ALL transitions when navigating (forward or backward).

    const Nav = StackNavigator({
      Screens
    },{
      transitionConfig,
      navigationOptions
    });
    

    in transitionConfig add this:

    const transitionConfig = () => ({
        transitionSpec: {
          duration: 0,
          timing: Animated.timing,
          easing: Easing.step0,
        },
      })
    

    The transitionConfig is a function that returns an object that overrides default screen transitions. https://reactnavigation.org/docs/navigators/stack

    • if someone knows a way to change animations on single navigation, I'd love to hear how!
    0 讨论(0)
  • 2020-12-28 15:56

    For 2020 / react-navigation-stack I use the following code when setting up the StackNavigator:

    import { createStackNavigator, CardStyleInterpolators } from 'react-navigation-stack';
    import { Easing } from 'react-native';
    
    const Navigator = createStackNavigator({
      // ...
    }, {
      defaultNavigationOptions: ({ navigation }) => {
        const animation = navigation.getParam('_animation');
        return {
          // ...
          cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
          ...(animation === 'back' && {
            gestureDirection: 'horizontal-inverted',
          }),
          ...(animation === 'skip' && {
            transitionSpec: {
              open: { animation: 'timing', config: { duration: 0, easing: Easing.step1 }, },
              close: { animation: 'timing', config: { duration: 0, easing: Easing.step0 }, },
            },
          }),
        };
      },
    });
    
    

    and the the _animation param to override the animation style

    // replace to a route not in the stack normally creates a forward animation, but
    // we want a backwards animation
    this.props.navigation.dispatch(
      StackActions.replace({ routeName: 'Login', params: { _animation: 'back' } })
    );
    
    0 讨论(0)
  • 2020-12-28 16:01

    This is my working solution for reset back to home (root) without creating new route

    if(this.categoriesNav.state.nav.index >0){
        let k = this.categoriesNav.state.nav.routes[1].key;
        this.categoriesNav.dispatch(NavigationActions.back({key: k})); }
    

    categoriesNav is referenced to my stack navigator

    0 讨论(0)
提交回复
热议问题