Prevent navigating twice when clicking a button quickly

Viewed 3497

I am using react-navigation and would like to prevent navigating to the same screen twice when the user tap/click a button quickly. Here is my reducer:

export const navReducer = (state = initialState, action = {}) => {
    let nextState;
    switch (action.type) {
        case TO_LOGIN:
            nextState = RootNav.router.getStateForAction(
                NavigationActions.reset({
                    index: 0,
                    actions: [NavigationActions.navigate({
                        type: NavigationActions.NAVIGATE,
                        routeName: TO_LOGIN
                    })],
                    key: null
                }), state);
            break;

        case TO_HOME:
            nextState = RootNav.router.getStateForAction(
                NavigationActions.reset({
                    index: 0,
                    actions: [NavigationActions.navigate({
                        type: NavigationActions.NAVIGATE,
                        routeName: TO_HOME
                    })],
                }), state);
            break;

        default:
            if (action.type === NavigationActions.NAVIGATE) {
                console.log('action: ' + JSON.stringify(action));
                console.log('state: ' + JSON.stringify(state));
                console.log('nextState: ' + JSON.stringify(RootNav.router.getStateForAction(action, state)));
            }

            nextState = RootNav.router.getStateForAction(action, state);
            break;
    }

    return nextState || state;
};

The output of the console.logs is:

First click:

action: {"type":"Navigation/NAVIGATE","routeName":"ClinicDetail","params":{"section":0,"from":"near"}}
state: {"index":0,"routes":[{"routeName":"TO_HOME","key":"id-1496294907150-4"}]}
nextState: {"index":0,"routes":[{"routeName":"TO_HOME","key":"id-1496294907150-4"}]}

Second click:

action: {"type":"Navigation/NAVIGATE","routeName":"ClinicDetail","params":{"section":0,"from":"near"}}
state: {"index":0,"routes":[{"routeName":"TO_HOME","key":"id-1496294907150-4"}]}
nextState: {"index":0,"routes":[{"routeName":"TO_HOME","key":"id-1496294907150-4"}]}

What kind of check to do so I can prevent this happening?

4 Answers

I fixed this bug by creating a module which calls a function only once in the passed interval.

Example: If you wish to navigate from Home -> About And you press the About button twice in say 400 ms.

navigateToAbout = () => dispatch(NavigationActions.navigate({routeName: 'About'}))

const pressHandler = callOnce(navigateToAbout,400);
<TouchableOpacity onPress={pressHandler}>
 ...
</TouchableOpacity>

The module will take care that it calls navigateToAbout only once in 400 ms.

Here is the link to the NPM module: https://www.npmjs.com/package/call-once-in-interval

Related