Skip to content

Instantly share code, notes, and snippets.

@imranariffin
Last active May 31, 2019 06:29
Show Gist options
  • Save imranariffin/82de73c488aa2d7994a6594f2d76e4d7 to your computer and use it in GitHub Desktop.
Save imranariffin/82de73c488aa2d7994a6594f2d76e4d7 to your computer and use it in GitHub Desktop.
React Native Navigation Redux Middleware Pattern
import { ToastAndroid } from 'react-native'
import { NavigationActions } from 'react-navigation'
import actions from './actions'
import routes from './routes'
let navigator
export default store => next => action => {
const actionType = action.type
const nextAction = next(action)
const nextState = store.getState()
if (!navigator) {
return nextAction
}
const routePath = getCurrentRoutePath(navigator.state.nav)
const currentRoute = routePath[routePath.length - 1]
switch (currentRoute) {
case routes.SCREEN_A: {
// Implicitly navigating to screen B based on some other action
if (actionType === actions.DONE_BUSINESS_IN_SCREEN_A) {
navigateTo(routes.SCREEN_B)
}
// Implicitly navigating to screen C based on some other action with payload
if (actionType === actions.DONE_BUSINESS_IN_SCREEN_A_WITH_SOME_PAYLOAD) {
navigateTo(routes.SCREEN_C, {
// ...somePayload
})
}
// Implicitly navigating to screen D based on some the state
if (
actionType === actions.DONE_BUSINESS_IN_SCREEN_A_WITH_SOME_PAYLOAD &&
state.someState == 'GOOD_TO_GO_SCREEN_D'
) {
navigateTo(routes.SCREEN_D, {
// ...somePayload
})
}
// Explictly navigating to screen E
if (actionType === actions.EXPLICITLY_GO_TO_SCREEN_E) {
navigateTo(routes.SCREEN_E)
}
// Navigate to error screen in case of error
const { error } = nextState // some error populated on the state
if (actionType === actions.SOME_ERROR_FROM_API && !!error) {
navigateTo(routes.SCREEN_ERROR, {
error,
})
}
break
}
case routes.SCREEN_B: {
// Some more navigation logics
break
}
case routes.SCREEN_C: {
// Some more navigation logics
break
}
case routes.SCREEN_D: {
// Some more navigation logics
break
}
case routes.SCREEN_E: {
// Some more navigation logics
break
}
case routes.SCREEN_ERROR: {
// Some more navigation logics
break
}
default: {
break
}
}
return nextAction
}
export const setTopLevelNavigator = (navigatorRef) => {
navigator = navigatorRef
}
const getCurrentRoutePath = (nav) => {
if (nav.index === undefined) {
return []
}
return recurseRoute(nav.routes[nav.index])
}
const navigateTo = (routeName, params = {}) => {
navigator.dispatch(
NavigationActions.navigate(
{
params,
routeName
}
)
)
}
const recurseRoute = (route, path = []) => {
const nextIndex = route.index
if (nextIndex === undefined) {
return path.concat([route.routeName])
}
return [ route.routeName ].concat(
recurseRoute(
route.routes[nextIndex],
path
)
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment