Going back to "previous tab" in TabRouter

566 Views Asked by At

In react-navigation, I wanted to use TabRouter but on this.props.navigation.goBack() I wanted it to go to the previous tab.

Does anyone have any idea how to go to previous tab, I was hoping it would as simple as setting backBehavior: 'previousTab'.

I have hacked solution here, but its a bad hack as I had to modify the lib files:

I was only able to accomplish this by setting backBehavior to initialRoute, and then on my TabRouter adding a custom getStateForAction like this:

const defaultGetStateForAction = HubNavigator.router.getStateForAction;

HubNavigator.router.getStateForAction = function(action, state) {
    switch (action.type) {
        case NavigationActions.INIT: {
                if (!this.TAB_HISTORY) this.TAB_HISTORY = [];
                this.TAB_HISTORY.length = 0;
                this.TAB_HISTORY.push({ index:ROUTE_INDEX[INITIAL_ROUTE_NAME], params:undefined }); // i dont think INIT ever has params - C:\Users\Mercurius\Pictures\Screenshot -  1, 2017 10.47 AM.png
            break;
        }
        case NavigationActions.NAVIGATE: {
                const { routeName } = action;
                this.TAB_HISTORY.push({ index:ROUTE_INDEX[routeName], params:action.params });
            break;
        }
        case NavigationActions.BACK: {
            if (this.TAB_HISTORY.length === 1) {
                BackHandler.exitApp();
                return null;
            } else {
                const current = this.TAB_HISTORY.pop();
                const previous = this.TAB_HISTORY[this.TAB_HISTORY.length - 1];
                const default_ = defaultGetStateForAction(action, state, ()=>{
                    console.log('returning previous index of:', previous.index);
                    return previous.index
                });
                default_.index = previous.index;
                default_.routes[previous.index].params = previous.params;
                return default_;
            }
        }
    }

    return defaultGetStateForAction(action, state);
}

What I do is, on NavigationActions.BACK I modify the returned object index to have the previous index, which I hold in the array this.TAB_HISTORY.

However when I start the app, switch from initial tab to tab 2, then from tab 2 back to initial tab... pressing "back" would do nothing this is because activeTabIndex is always set to initialRouteIndex here - https://github.com/react-community/react-navigation/blob/5e075e1c31d5e6192f2532a815b1737fa27ed65b/src/routers/TabRouter.js#L138

So you see in my fix above I pass a third argument to defaultGetStateForAction which returns the index, but I had to modify react-navigation/src/routers/TabRouter.js for this, which is not what I want to do.

Does anyone have any idea how to go to previous tab, I was hoping it would as simple as setting backBehavior: 'previousTab'.

Here is my HubNavigator in case you want to see that:

const ROUTE_INDEX = { Players: 0, Girls: 1, Customers: 2, Assets: 3 };
const INITIAL_ROUTE_NAME = 'Players';
const HubNavigator = TabNavigator(
    {
        Players:   { screen:ScreenPlayers },
        Girls:     { screen:ScreenGirls },
        Customers: { screen:ScreenCustomers },
        Assets:    { screen:ScreenAssets }
    },
    {
        initialRouteName: INITIAL_ROUTE_NAME,
        backBehavior: 'initialRoute',
        cardStyle: styles.card,
        order: Object.entries(ROUTE_INDEX).sort(([,indexA], [,indexB]) => indexA - indexB).map(([routeName]) => routeName),
    }
)
0

There are 0 best solutions below