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

前端 未结 7 727
灰色年华
灰色年华 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

提交回复
热议问题