Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Navigation 2: How to check previous scene and to disable tab change

I have a tab navigation. One of my tabs has a form and I would like to disable navigate event if my form data is not saved.

In ver.1, the tabBarOnPress method provides previousScene, scene and jumpToIndex, so I was able to check which scene I am leaving and to access its props.

Now in ver.2, the tabBarOnPress method provides the navigation props for the scene, but the previous scene prop is missing :/

navigationOptions: {
    tabBarOnPress: ({ navigation, defaultHandler }) => {
        // Check the previous screen
        // If I am leaving the home screen and the user has unsaved data
        // disable tab navigation
        // else change to the pressed tab
    },
},

Also, I tried with the navigation event listeners but the NAVIGATE action is already dispatched:

props.navigation.addListener('willBlur', () => {
    // Disable tab switching;
}),

Simple snack: https://snack.expo.io/@hristoeftimov/handle-tab-changes-in-react-navigation-v2

Any solutions how to disable tab switching before leave a tab?

like image 668
Hristo Eftimov Avatar asked Oct 26 '18 12:10

Hristo Eftimov


People also ask

How do I go back to previous screen in react navigation?

You can go back to an existing screen in the stack with navigation. navigate('RouteName') , and you can go back to the first screen in the stack with navigation.

How do I remove the tab bar border in react navigation?

Customize the TabBar This property is commonly used to change the styles of the tab bar, for example, by applying the backgroundColor styles' property. To remove the border, add the tabBarOptions prop and inside it, add a style property called borderTopWidth with a value 0 .


1 Answers

I have found a much simpler way, using the getStateForAction.

const defaultGetStateForAction = MainStack.router.getStateForAction;
MainStack.router.getStateForAction = (action, state) => {
    if (!state) {
        return defaultGetStateForAction(action, state);
    }

    if (
        action.type === NavigationActions.NAVIGATE
        && state.routes[state.index].key === 'HomeTab'
    ) {
        const tab = state.routes[state.index];
        const currentRoute = tab.routes[tab.index];
        const currentRouteParams = currentRoute.params;

        if (currentRouteParams && currentRouteParams.isNavigationDisabled) {
            return currentRouteParams.showConfirmationDialog(action);
        }
    }

    return defaultGetStateForAction(action, state);
}

Every time when I switch between the tabs it jumps into getStateForAction where I can access the leaving tab (from state) and the next screen (from action).

So, when my action is NAVIGATE and the leaving screen/route is HoneTab I can change/disable the default state for action and to trigger showConfirmationDialog() - This is a function that I can set as a route parameter to my HomeTab screen.

like image 109
Hristo Eftimov Avatar answered Sep 21 '22 01:09

Hristo Eftimov