Skip to content

Instantly share code, notes, and snippets.

@aphillipo
Created October 5, 2015 19:26
Show Gist options
  • Save aphillipo/0583601b0deab1e89dcf to your computer and use it in GitHub Desktop.
Save aphillipo/0583601b0deab1e89dcf to your computer and use it in GitHub Desktop.
Wrapping React Native Navigator
class MainApp extends Component {
constructor(props) {
super(props);
}
renderScene(route, navigator) {
var Component = route.component;
return (
<Component route={route} navigator={navigator} />
);
}
render() {
return (
<Router renderScene={this.renderScene} {...this.props} />
);
}
}
export Main = connect((state) => {
return {
currentRoute: state.route.currentRoute
}
})(MainApp);
function props(dispatch) {
return {
navigateToPage2: () => {
dispatch(navigateTo('Page2'));
},
}
}
import * as actionTypes from '../actions/actionTypes';
import assign from 'object-assign';
var initialState = {
currentRoute: ''
};
export function route(state=initialState, action={}) {
switch (action.type) {
case actionTypes.NAVIGATE_TO:
return assign({}, state, { currentRoute: action.routeName });
break;
}
}
export function navigateTo(routeName) {
return {
type: actionTypes.NAVIGATE_TO,
routeName
};
}
// Navigation singleton. registers components as a map
import _ from 'lodash';
import React, { Component, Navigator } from 'react-native';
import routerRegistry from './RouterRegistry';
const BACK = 'BACK';
const FORWARD = 'FORWARD';
export class Router extends Component {
static defaultProps = {
currentRoute: false
};
constructor() {
super();
this.routeNames = [routerRegistry.getInitialRoute().name];
}
navigateTo(name) {
var route = routerRegistry.getRouteByName(name),
routeIndex = this.routeNames.indexOf(name);
if (routeIndex > -1) {
this.routeNames = this.routeNames.slice(0, routeIndex + 1);
route.direction = BACK;
this.refs.navigator.popToRoute(route);
} else {
this.routeNames.push(name);
route.direction = FORWARD;
this.refs.navigator.push(route);
}
}
componentWillReceiveProps(nextProps) {
if (this.props.currentRoute !== nextProps.currentRoute) {
// change the current page to navigate
this.navigateTo(nextProps.currentRoute);
}
}
render() {
return <Navigator
ref="navigator"
initialRoute={routerRegistry.getInitialRoute()}
{...this.props}
configureScene={(route) => (route.direction === BACK) ? Navigator.SceneConfigs.FloatFromRight : Navigator.SceneConfigs.FloatFromLeft;}/>
}
}
const SINGLETON = Symbol();
import _ from 'lodash';
let instance = null;
class RouterRegistry {
constructor() {
this.routes = {};
this.initialRoute = null;
}
registerRoute(route) {
if (_.size(this.routes) === 0) {
this.initialRoute = route;
}
this.routes[route.name] = route;
}
unregisterRouteByName(name) {
this.routes = _.filter(this.routes, (o) => { return o.name !== name; })
}
unregisterRoute(route) {
this.unregisterRouteByName(route.name);
}
getRouteByName(name) {
if (name in this.routes) {
return this.routes[name];
} else {
throw Error('Please register a page before trying to find it.')
}
}
getInitialRoute() {
return this.initialRoute;
}
}
if (!instance) {
instance = new RouterRegistry();
}
export default instance;
// register all of our top level components here, so we need to require them all.
import routerRegistry from './RouterRegistry';
import Page1 from '../components/Page1';
import Page2 from '../components/Page2';
import Page3 from '../components/Page3';
routerRegistry.registerRoute({
name: 'Page1',
component: Page1
});
routerRegistry.registerRoute({
name: 'Page2',
component: Page2
});
routerRegistry.registerRoute({
name: 'Page3',
component: Page3
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment