Skip to content

Instantly share code, notes, and snippets.

@mschipperheyn
Last active Jan 29, 2016
Embed
What would you like to do?
import React, { Navigator } from 'react-native';
import RouterRegistry from './RouterRegistry';
import navigateTo from './routerActions';
const BACK = 'BACK';
const FORWARD = 'FORWARD';
class Router extends React.Component {
static propTypes = {
registry: React.PropTypes.object.isRequired
};
static defaultProps = {
currentRoute: false
};
constructor(props) {
super(props);
this.routeNames = [props.registry.getInitialRoute().path];
}
navigateTo(path) {
let route = this.props.registry.getRouteByPath(path);
let routeIndex = this.routeNames.indexOf(path);
if (routeIndex > -1) {
this.routeNames = this.routeNames.slice(0, routeIndex + 1);
route.direction = BACK;
this.refs.navigator.popToRoute(route);
} else {
this.routeNames.push(path);
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={this.props.registry.getInitialRoute()}
{...this.props}
configureScene={(route) => (route.direction === BACK) ? Navigator.SceneConfigs.FloatFromRight : Navigator.SceneConfigs.FloatFromLeft}/>
}
}
export {
Router,
RouterRegistry,
navigateTo
}
import * as actionTypes from './routerConstants';
export default function navigateTo(path) {
return {
type: actionTypes.NAVIGATE_TO,
path
};
}
export const NAVIGATE_TO = "NAVIGATE_TO";
'use strict';
import React from 'react-native';
import { connect } from 'react-redux/native';
import { Router, RouterRegistry, navigateTo } from '../components/router/Router';
export default class RouterExample extends React.Component{
_getRouterRegistry(){
let registry = new RouterRegistry({
initialRoute:{
path:'/',
title:'',
component:() => require('./LoadingScreen')
}
});
registry.registerRoutes([
{path:'/login',title:'Login',component: () => require('./LoginScreen')},
{path:'/account/home',title:'Home',component: () => require('./HomeScreen')}
]);
return registry;
}
renderScene(route,navigator){
if(route){
let Component = route.component();
return (
<Component route={route} navigator={navigator}/>
);
}
}
render(){
return (
<View style={{flex:1,position:'relative'}}>
<Router
currentRoute={this.state.currentRoute}
registry={this._getRouterRegistry()}
renderScene={this.renderScene}
navigationBar={this._getNavbar()}
{...this.props} />
</View>
);
}
}
import * as actionTypes from './routerConstants';
var initialState = {
currentRoute: null
};
export default function route(state=initialState, action={}) {
switch (action.type) {
case actionTypes.NAVIGATE_TO:
return {...state,...{
currentRoute: action.path
}};
default:
return state;
}
}
export default class RouterRegistry {
constructor(options) {
this.routes = {};
options.initialRoute && this.registerRoute(options.initialRoute);
}
registerRoute(route) {
if (Object.keys(this.routes).length === 0) {
this.initialRoute = route.path;
}
this.routes[route.path] = route;
}
registerRoutes(routes) {
for(let route of routes){
this.registerRoute(route);
}
}
unregisterRouteByPath(path) {
this.routes = this.routes.filter((o) => { return o.path !== path; })
}
unregisterRoute(route) {
this.unregisterRouteByName(route.path);
}
getRouteByPath(path) {
if (path in this.routes) {
return this.routes[path];
} else {
throw Error('Please register a page before trying to find it.')
}
}
getInitialRoute() {
return this.getRouteByPath(this.initialRoute);
}
}
@patelsan

This comment has been minimized.

Copy link

@patelsan patelsan commented Nov 9, 2015

Thanks for sharing this. Could you please share the _getNavbar()? I am dispatching the navigateTo action on 'Back', however router is running in to following error while calling popToRoute inspite of the route being valid.

react native calling popToRoute for route that doesn't exist

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