Skip to content

Instantly share code, notes, and snippets.

@fabriciovergara
Created March 5, 2017 10:48
Show Gist options
  • Save fabriciovergara/fecad2389adbb1086a2d458e88f36a3d to your computer and use it in GitHub Desktop.
Save fabriciovergara/fecad2389adbb1086a2d458e88f36a3d to your computer and use it in GitHub Desktop.
React-Navigation AuthFlow with Saga
import { effects } from 'redux-saga';
import { NavigationActions } from 'react-navigation';
import { redirect } from './action';
import NavigationConfiguration from '../configuration/NavigationConfiguration';
import {
REDIRECT,
AUTHENTICATE,
UNAUTHENTICATE,
} from './constants';
const navConfig = new NavigationConfiguration();
const isAuthenticatedRouteName = navConfig.isAuthenticatedRouteName;
const isUnauthenticatedRouteName = navConfig.isUnauthenticatedRouteName;
const initialAuthenticatedRouteName = navConfig.getInitialAuthenticatedRouteName();
const initialUnauthenticatedRouteName = navConfig.getInitialUnauthenticatedRouteName();
function* redirectFlow() {
const state = yield effects.select();
const authenticated = state.auth.authenticated;
const index = state.nav.index;
const routeName = state.nav.routes[index].routeName;
const redirectRoute = (name, childRouteName) => NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: name })
],
});
if (authenticated && !isAuthenticatedRouteName(routeName)) {
yield effects.put(redirectRoute(initialAuthenticatedRouteName))
} else if (!authenticated && !isUnauthenticatedRouteName(routeName)) {
yield effects.put(redirectRoute(initialUnauthenticatedRouteName))
}
}
function* authenticateFlow() {
yield effects.put(redirect());
}
function* unauthenticateFlow() {
yield effects.put(redirect());
}
export default function* root() {
yield effects.takeLatest(REDIRECT, redirectFlow);
yield effects.takeLatest(AUTHENTICATE, authenticateFlow);
yield effects.takeLatest(UNAUTHENTICATE, unauthenticateFlow);
}
import React from 'react'
import { connect } from 'react-redux'
import { redirect as redirectAction } from 'src/redux/auth/action';
class Index extends React.Component {
static propTypes = {
redirect: React.PropTypes.func.isRequired,
};
componentDidMount() {
this.props.redirect();
}
render() {
return null;
}
}
export default connect(null, { redirect: () => redirectAction() })(Index);
import React from 'react';
import { addNavigationHelpers, StackNavigator } from 'react-navigation';
import { connect } from 'react-redux';
import { styles } from '../../components/Container'
import Index from '../../containers/Index';
import Home from '../../containers/Home';
import Login from '../../containers/Login';
const NAV_ID = 'nav';
const INITIAL_AUTHENTICATED_ROUTE_NAME = 'Home';
const INITIAL_UNAUTHENTICATED_ROUTE_NAME = 'Login';
const AUTHENTICATED_ROUTES = {
Home: { screen: Home },
};
const UNAUTHENTICATED_ROUTES = {
Login: { screen: Login },
};
const AppNavigator = StackNavigator({
Index: { screen: Index, },
...AUTHENTICATED_ROUTES,
...UNAUTHENTICATED_ROUTES,
}, {
initialRouteName: 'Index',
});
const ConnectedAppNavigator = connect(state => ({ [NAV_ID]: state[NAV_ID] }))(props => (
<AppNavigator style={styles.typeFill} navigation={addNavigationHelpers({
dispatch: props.dispatch,
state: props[NAV_ID]
})}/>
));
export default class NavigationConfiguration {
getAppNavigator() {
return ConnectedAppNavigator;
}
isAuthenticatedRouteName(routeName) {
return !!AUTHENTICATED_ROUTES[routeName];
}
isUnauthenticatedRouteName(routeName) {
return !!UNAUTHENTICATED_ROUTES[routeName];
}
getInitialAuthenticatedRouteName(){
return INITIAL_AUTHENTICATED_ROUTE_NAME;
}
getInitialUnauthenticatedRouteName(){
return INITIAL_UNAUTHENTICATED_ROUTE_NAME;
}
getReducerId() {
return NAV_ID;
}
getReducer() {
return {
[NAV_ID]: (state, action) =>
AppNavigator.router.getStateForAction(action, state) || state,
}
}
}
@ronnyhartenstein
Copy link

ronnyhartenstein commented Mar 6, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment