Skip to content

Commit

Permalink
add more Redux support, demo, issues #56, #152, #158, #167, #183, #184
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavlo Aksonov authored and Pavlo Aksonov committed Feb 9, 2016
1 parent 40ca8a1 commit 78e5a7d
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 59 deletions.
49 changes: 42 additions & 7 deletions Actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ import Route from './Route';
import Router from './Router';
import debug from './debug';

const BEFORE_ROUTE = 'BEFORE_ROUTER_ROUTE';
const AFTER_ROUTE = 'AFTER_ROUTER_ROUTE';
const BEFORE_POP = 'BEFORE_ROUTER_POP';
const AFTER_POP = 'AFTER_ROUTER_POP';
const BEFORE_DISMISS = 'BEFORE_ROUTER_DISMISS';
const AFTER_DISMISS = 'AFTER_ROUTER_DISMISS';

function isNumeric(n){
return !isNaN(parseFloat(n)) && isFinite(n);
}
Expand Down Expand Up @@ -58,29 +65,45 @@ class Actions {
router = route.parent;
debug("Switching to router="+router.name);
}
debug("ROUTER DELEGATE PROPS:"+ router.delegate.props.dispatch)
const currentRoute = router.routes[name];
if (router.delegate.props && router.delegate.props.dispatch){
router.delegate.props.dispatch({...props, type: BEFORE_ROUTE, route:currentRoute, name})
}
if (router.route(name, props)){

// deep into child router
while (router.currentRoute.childRouter){
router = router.currentRoute.childRouter;
debug("Switching to child router="+router.name);
}

this.currentRouter = router;
if (router.delegate.props && router.delegate.props.dispatch){
router.delegate.props.dispatch({...props, type: AFTER_ROUTE, route:currentRoute, name})
}
return true;
}
return false;
}
dismiss(){
dismiss(props: { [key: string]: any} = {}){
props = filterParam(props);
let router: Router = this.currentRouter;
// go to root router
while (router.parentRoute){
router = router.parentRoute.parent;
debug("Switching to parent router="+router.name);
}
return router.dismiss();
if (router.delegate.props && router.delegate.props.dispatch){
router.delegate.props.dispatch({...props, type: BEFORE_DISMISS, route:router.currentRoute, name:router.currentRoute.name})
}
const res = router.dismiss();
if (router.delegate.props && router.delegate.props.dispatch){
router.delegate.props.dispatch({...props, type: AFTER_DISMISS, route:router.currentRoute, name:router.currentRoute.name})
}
return res;
}
pop(num: number = 1){
pop(num: number = 1, props: { [key: string]: any} = {}){
props = filterParam(props);
if (!isNumeric(num)){
num = 1;
}
Expand All @@ -106,8 +129,14 @@ class Actions {
break;
}
}
if (router.pop()){
if (router.delegate.props && router.delegate.props.dispatch){
router.delegate.props.dispatch({...props, type: BEFORE_POP, route:router.currentRoute, name:router.currentRoute.name})
}
if (router.pop(1, props)){
this.currentRouter = router;
if (router.delegate.props && router.delegate.props.dispatch){
router.delegate.props.dispatch({...props, type: AFTER_POP, route:router.currentRoute, name:router.currentRoute.name})
}
return true;
} else {
return false;
Expand All @@ -116,5 +145,11 @@ class Actions {
}
}
}

export default new Actions();
const actions = new Actions();
actions.BEFORE_ROUTE = BEFORE_ROUTE;
actions.AFTER_ROUTE = AFTER_ROUTE;
actions.BEFORE_POP = BEFORE_POP;
actions.AFTER_POP = AFTER_POP;
actions.BEFORE_DISMISS = BEFORE_DISMISS;
actions.AFTER_DISMISS = AFTER_DISMISS;
export default actions;
3 changes: 0 additions & 3 deletions ExRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,6 @@ export default class ExRouter extends React.Component {
const Footer = this.props.footer;
const footer = Footer ? <Footer {...this.props} {...this.state}/> : null;
debug("RENDER ROUTER:",router.name);
debug(Object.keys(router.routes));
debug(router.stack);

return (
<View style={styles.transparent}>
{header}
Expand Down
107 changes: 70 additions & 37 deletions Example/Example.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,41 @@ var Launch = require('./components/Launch');
var Register = require('./components/Register');
var Login = require('./components/Login');
var Login2 = require('./components/Login2');
var {Router, Route, Schema, Animations, TabBar} = require('react-native-router-flux');
var RNRF = require('react-native-router-flux');
var {Route, Schema, Animations, Actions, TabBar} = RNRF;
var Error = require('./components/Error');
var Home = require('./components/Home');
var TabView = require('./components/TabView');
import { createStore } from 'redux'
import { Provider, connect } from 'react-redux'

function reducer(state = {}, action) {
switch (action.type) {
case Actions.BEFORE_ROUTE:
console.log("BEFORE_ROUTE:", action);
return state;
case Actions.AFTER_ROUTE:
console.log("AFTER_ROUTE:", action);
return state;
case Actions.AFTER_POP:
console.log("AFTER_POP:", action);
return state;
case Actions.BEFORE_POP:
console.log("BEFORE_POP:", action);
return state;
case Actions.AFTER_DISMISS:
console.log("AFTER_DISMISS:", action);
return state;
case Actions.BEFORE_DISMISS:
console.log("BEFORE_DISMISS:", action);
return state;
default:
return state;
}

}
let store = createStore(reducer);
const Router = connect()(RNRF.Router);

class TabIcon extends React.Component {
render(){
Expand All @@ -28,43 +59,45 @@ class Header extends React.Component {
export default class Example extends React.Component {
render() {
return (
<Router hideNavBar={true} name="root">
<Schema name="modal" sceneConfig={Navigator.SceneConfigs.FloatFromBottom}/>
<Schema name="default" sceneConfig={Navigator.SceneConfigs.FloatFromRight}/>
<Schema name="withoutAnimation"/>
<Schema name="tab" type="switch" icon={TabIcon} />
<Provider store={store}>
<Router hideNavBar={true} name="root">
<Schema name="modal" sceneConfig={Navigator.SceneConfigs.FloatFromBottom}/>
<Schema name="default" sceneConfig={Navigator.SceneConfigs.FloatFromRight}/>
<Schema name="withoutAnimation"/>
<Schema name="tab" type="switch" icon={TabIcon} />

<Route name="register" component={Register} title="Register"/>
<Route name="home" component={Home} title="Replace" type="replace"/>
<Route name="login" schema="modal">
<Router name="loginRouter">
<Route name="loginModal" component={Login} schema="modal"/>
<Route name="loginModal2" hideNavBar={true} component={Login2} title="Login2"/>
</Router>
</Route>
<Route name="register2" component={Register} title="Register2" schema="withoutAnimation"/>
<Route name="error" type="modal" component={Error}/>
<Route name="tabbar">
<Router footer={TabBar} showNavigationBar={false}>
<Route name="tab1" schema="tab" title="Tab #1" >
<Router onPop={()=>{console.log("onPop is called!"); return true} }>
<Route name="tab1_1" component={TabView} title="Tab #1_1" />
<Route name="tab1_2" component={TabView} title="Tab #1_2" />
</Router>
</Route>
<Route name="tab2" schema="tab" title="Tab #2" hideNavBar={true}>
<Router onPop={()=>{console.log("onPop is called!"); return true} }>
<Route name="tab2_1" component={TabView} title="Tab #2_1" />
<Route name="tab2_2" component={TabView} title="Tab #2_2" />
</Router>
</Route>
<Route name="tab3" schema="tab" title="Tab #3" component={TabView} hideTabBar={true}/>
<Route name="tab4" schema="tab" title="Tab #4" component={TabView} />
<Route name="tab5" schema="tab" title="Tab #5" component={TabView} />
</Router>
</Route>
<Route name="launch" header={Header} initial={true} component={Launch} wrapRouter={true} title="Launch" hideNavBar={true}/>
</Router>
<Route name="register" component={Register} title="Register"/>
<Route name="home" component={Home} title="Replace" type="replace"/>
<Route name="login" schema="modal">
<Router name="loginRouter">
<Route name="loginModal" component={Login} schema="modal"/>
<Route name="loginModal2" hideNavBar={true} component={Login2} title="Login2"/>
</Router>
</Route>
<Route name="register2" component={Register} title="Register2" schema="withoutAnimation"/>
<Route name="error" type="modal" component={Error}/>
<Route name="tabbar">
<Router footer={TabBar} showNavigationBar={false}>
<Route name="tab1" schema="tab" title="Tab #1" >
<Router onPop={()=>{console.log("onPop is called!"); return true} }>
<Route name="tab1_1" component={TabView} title="Tab #1_1" />
<Route name="tab1_2" component={TabView} title="Tab #1_2" />
</Router>
</Route>
<Route name="tab2" schema="tab" title="Tab #2" hideNavBar={true}>
<Router onPop={()=>{console.log("onPop is called!"); return true} }>
<Route name="tab2_1" component={TabView} title="Tab #2_1" />
<Route name="tab2_2" component={TabView} title="Tab #2_2" />
</Router>
</Route>
<Route name="tab3" schema="tab" title="Tab #3" component={TabView} hideTabBar={true}/>
<Route name="tab4" schema="tab" title="Tab #4" component={TabView} />
<Route name="tab5" schema="tab" title="Tab #5" component={TabView} />
</Router>
</Route>
<Route name="launch" header={Header} initial={true} component={Launch} wrapRouter={true} title="Launch" hideNavBar={true}/>
</Router>
</Provider>
);
}
}
6 changes: 4 additions & 2 deletions Example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
"start": "node_modules/react-native/packager/packager.sh"
},
"dependencies": {
"react-native": "^0.17",
"react-native": "^0.19",
"react-native-button": "^1.2.1",
"react-native-router-flux": "^2.1.9"
"react-native-router-flux": "^2.2.0",
"react-redux": "^4.4.0",
"redux": "^3.3.1"
}
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ This component is not opinionated and does not depend on any implementation of F
All route actions can be hooked by adding handlers for `Actions.onPush`, `Actions.onReplace`, `Actions.onPop` in your store(s).

If a handler returns false, the route action is ignored. For Redux, you will need to 'connect' your component to your store.
If 'dispatch' prop is passed to the router, it will be called with current route as `route`, `name` as route name and all route props, check Example for more details.

For example, instead of
```
Expand Down
3 changes: 2 additions & 1 deletion ReactRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import React from 'react-native'
import Router from './Router';
import ExRouter from './ExRouter';
const {StyleSheet, View} = React;
import debug from './debug';
import Actions from './Actions';
export default class extends React.Component {

Expand All @@ -32,6 +33,6 @@ export default class extends React.Component {

render(){
const Component = this.props.router || ExRouter;
return (<Component ref="router" {...this.props} router={this.router} />);
return (<Component ref="router" {...this.props} router={this.router} dispatch={this.props.dispatch}/>);
}
}
14 changes: 7 additions & 7 deletions Router.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ import Actions from './Actions';
import debug from './debug';

export class RouterDelegate {
onPush(name:string, props:{ [key: string]: any}):boolean {
onPush(route:Route, props:{ [key: string]: any}):boolean {
return true;
}
onPop(name:string, props:{ [key: string]: any}): boolean {
onPop(num: number = 1, route:Route, props:{ [key: string]: any}): boolean {
return true;
}
onReplace(name:string, props:{ [key: string]: any}):boolean {
onReplace(route:Route, props:{ [key: string]: any}):boolean {
return true;
}
onReset(name:string, props:{ [key: string]: any}):boolean {
onReset(route:Route, props:{ [key: string]: any}):boolean {
return true;
}
onSwitch(name:string, props:{ [key: string]: any}):boolean {
onSwitch(route:Route, props:{ [key: string]: any}):boolean {
return true;
}
}
Expand Down Expand Up @@ -199,12 +199,12 @@ export default class Router {
}
}

pop(num: number = 1){
pop(num: number = 1, props:{ [key: string]: any} = {}){
if (this._stack.length <= num){
return false;
}
this.nextRoute = null;
if (this.delegate.onPop && this.delegate.onPop(num)){
if (this.delegate.onPop && this.delegate.onPop(num, this.currentRoute, props)){
const routes = this._stack.splice(-num, num);
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion debug.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export default function debug(msg, param){
export default function debug(msg){
//console.log(msg);
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-router-flux",
"version": "2.1.9",
"version": "2.2.0",
"description": "React Native Router using Flux architecture",
"repository": {
"type": "git",
Expand Down

0 comments on commit 78e5a7d

Please sign in to comment.