Skip to content

Instantly share code, notes, and snippets.

@ethan605
Last active June 8, 2017 01:02
Show Gist options
  • Save ethan605/64140bde2f18763320a9f951b778f07b to your computer and use it in GitHub Desktop.
Save ethan605/64140bde2f18763320a9f951b778f07b to your computer and use it in GitHub Desktop.
A middleware for `react-navigation` library to prevent duplicated navigates. Note that is is a hack/workaround that works but not an official solution for React Navigation.
/*
* Examples for RoutersMiddleware
* For each action, we check if it is allowed to navigate.
*/
import RoutersMiddleware from './RoutersMiddleware';
export default function mainRouterReducer(state, action) {
const shouldNavigate = RoutersMiddleware.shouldNavigate(action, 'mainRouter');
// Duplicated navigate, keep the states the same
if (!shouldNavigate) return state;
return MainStack.router.getStateForAction(action, state) || state;
}
/**
* A middleware to detect short-time action dispatches
* This will check all 'Navigation/' prefixed actions
* which are duplicated over a short duration (`DISPATCH_THROTTLE`)
* and prevent them to be reduced to make new states.
*/
import Singleton from 'singleton';
import _ from 'lodash';
const LOG_DUPLICATED_NAVIGATES = true; // Loggings enabled
const DISPATCH_THROTTLE = 100; // miliseconds
class RoutersMiddleware extends Singleton {
constructor() {
super();
this.lastActions = {};
this.lastDispatchTimes = {};
}
shouldNavigate = (action, routerName) => {
// Only watch for 'Navigation/' prefixed actions, others are allowed
if (!_.startsWith(action.type, 'Navigation/')) return true;
const dispatchTime = Date.now();
const actionString = JSON.stringify(action);
const { [routerName]: lastActionString } = this.lastActions;
const { [routerName]: lastDispatchTime } = this.lastDispatchTimes;
if (actionString === lastActionString && lastDispatchTime + DISPATCH_THROTTLE < dispatchTime) {
if (LOG_DUPLICATED_NAVIGATES) console.log('Duplicated navigate action', action);
return false;
}
this.lastActions[routerName] = actionString;
this.lastDispatchTimes[routerName] = dispatchTime;
return true;
}
}
export default RoutersMiddleware.get();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment