Last active
June 8, 2017 01:02
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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