Simple router for Redux universal applications. Can be used with React too.
npm install routex
Routex needs some abstraction over browser history, we recommend to use rackt/history^1.0.0
import { createRoutex, actions } from 'routex';
import { compose, createStore, combineReducers } from 'redux';
import { createHistory } from 'history';
const routes = [
{
path: '/',
children: [
{
path: 'about',
children: [/* ... */]
}
],
attrs: {
custom: true // optional custom attributes to assign to route
}
}/* ... */
];
// this will return object with high order store and reducer
const routex = createRoutex(routes, createHistory(), () => console.log('Transition finished') );
const newCreateStore = compose(routex.store, createStore);
const routexReducer = routex.reducer;
const reducers = combineReducers({ ...routexReducer /* your reducers */ });
const store = newCreateStore(reducers);
store.dispatch(actions.transitionTo('/about')); // transitions to about
store.generateLink('about'); // generates link object (see api)
import { createRoutex } from 'routex';
import { compose, createStore, combineReducers } from 'redux';
import React, { Component } from 'react';
import { View, Link } from 'routex/lib/react';
import { createHistory } from 'history';
class App extends Component {
render() {
//this props children contains nested route
// so everywhere when you can render nested routes you need to do this
return (
<div>
<Link route={'about'} params={{}} />
{this.props.children}
</div>
);
}
}
const routes = [
{
path: '/',
component: App, // you need components in all routes because <View /> needs to render them
attrs: {}, // default attrs
children: [
{
path: 'about',
attrs: { test: 1 },
component: () => Promise.resolve(About),
children: () => Promise.resolve([{ path: '/', component: Child }])
}
]
}/* ... */
];
// this will return object with high order store and reducer
const routex = createRoutex(routes, createHistory(), () => console.log('Transition finished') );
const newCreateStore = compose(routex.store, createStore);
const routexReducer = routex.reducer;
const reducers = combineReducers({ ...routexReducer /* your reducers */ });
const store = newCreateStore(reducers);
React.render(
<Provider store={store}>
<View />
</Provider>
, document.getElementById('App')
);
import { Router } from 'routex';
import { createHistory } from 'history';
const router = new Router([/* routes */], createHistory() /*, optional onTransition hook */);
router.listen(); // start listening to pop state events (immediately will start transition for current location)
// if you want to transition to another location you have to run this
// if you won't then router will lose track of current location and will pretend
// that location didn't change
router.run('/where-you-want-to-go', { /* query params object */});
-
Router
:constructor(routes, history, onTransition, resolveOnLoad)
:routes
(RouteObject[]
) array of route objects (see below)history
(HistoryObject
) history object (see below)onTransition
(Function(error: ?Error, resolvedRoute: ?Object
) optional function called every time router resolves/rejects routeresolveOnLoad
(Boolean
) optional, should route onEnter handlers be called on initial load? (useful if page is rendered in node, so we don't want to run onEnter again)
wrapOnEnterHandler(wrapper)
:wrapper
(Function(Function)
):- wrapper is function receiving route onEnter handler and returning its result
- can be used to decorate onEnter handler (e.g. passing some variables, etc)
- it will be called with original handler bound to default arguments (see routeObject) as a first argument
router.wrapOnEnterHandler((onEnter) => onEnter(someVar)
will append someVar to default onEnter argument list
wrapOnLeaveHandler(wrapper)
:wrapper
(Function(Function)
):- wrapper is function receiving route onLeave handler and returning its result
- can be used to decorate onLeave handler (e.g. passing some variables, etc)
- it will be called with original handler bound to default arguments (see routeObject) as a first argument
router.wrapOnLeaveHandler((onLeave) => onLeave(someVar)
will append someVar to default onLeave argument list
createHref(pathname, query):String
pathname
(String
) - url pathnamequery
(?Object.<String, *>
) - optional query parameters- creates link
currentRoute():null|RouteObject
returns current routeaddChangeStartListener(listener:Function):Function
- returns unsubscribe functionaddChangeSuccessListener(listener:Function):Function
- returns unsubscribe functionaddChangeFailListener(listener:Function):Function
- returns unsubscribe functionaddNotFoundListener(listener:Function):Function
- returns unsubscribe functionrun(path, query):Promise
:path
(String
) - url pathnamequery
(?Object.<String, *>
) - optional query parameters- resolves route for given pathname
listen()
- starts listening to history pop events (and will fire POPstate event immediately afterlisten()
call
-
createRoutex(routes, history, onTransition, resolveOnLoad)
routes
(RouteObject[]
) array of RouteObject (see below)history
(HistoryObject
) history object (see below)onTransition
(Function(error: ?Error, resolvedRoute: ?Object
) optional function called every time router resolves/rejects routeresolveOnLoad
(Boolean
) optional, should route onEnter handlers be called on initial load? (useful if page is rendered in node, so we don't want to run onEnter again)- returns (
Object
)store
(Function
) - high order store functionreducer
({ router: Function }
) - object usable incombineReducers
ofredux
-
actions.transitionTo(pathname, query)
- creates action, that routex store will try to transition to
path
(String
) - path without query string of new routequery
(Object.<String, *>
) - optional, parsed query string parameters to object
-
RouteObject:
(Object
):path
(String
) - route path (regexp will be created from it)/path:variable
/path/:variable
/path/:variable{\\d+}
- variable should be number
component
(Function|ReactElement
) ReactElement (optional)|Function:Promise`- returns ReactElement or
Function
returningPromise
resolving to ReactElement - ReactElement is required only in case that you are using
<View />
with React otherwise component can be anything you want - can be async, have to be a function returning a Promise otherwise it is sync
- returns ReactElement or
?children
(RouteObject[]
)- optional array of RouteObjects or function returning Promise (which resolves to array of RouteObjects)
?onEnter
(Function
)- optional route onEnter handler function
- function used to determine if router can transition to this route (can be used as guard, or to load data needed for view to store)
- this function is called on popState (moving in browser history using back/forward buttons), on
<Link />
click or dispatchingtransitionTo
- function signature is
function (currentRoute, nextRoute, router):Promise
if is used outside of createRoutex - function signature is
function (currentRoute, nextRoute, router, dispatch, getState):Promise
if is used by createRoutex, because it is wrappedcurrentRoute
(RouteObject|null
)` - current state of routexnextRoute
(RouteObject
) - route we are transitioning torouter
: (Router
) - instance of router- returns
Promise
- if promise is resolved, transition will finish and changes the state of the router reducer
- if promise is rejected, transition will finish but it won't change the state of the router reducer
?onLeave
(Function
)- optional route onLeave handler function
- signature is same as in the
onEnter
- function used to determine if router can transition from this route (can be used as guard, ...) to a new route
- this function is called on popState (moving in browser history using back/forward buttons), on
<Link />
click or dispatchingtransitionTo
?attrs
(Object
)- optional object of attributes assigned to route
- is overridden by child attributes if have same key name
-
HistoryObject:
(Object
):- abstraction over browser history
listen
(Function(Function(LocationObject))
) -- method used to register history change events listeners (pop and push)
pushState
(Function(state, path)
)- pushes state for given path
state
(?Object
) - state stored for given pathpath
(String)
- full path with query parameters
replaceState
(Function(state, path)
)- replaces current state with given state and path
state
(?Object
) - state stored for given pathpath
(String)
- full path with query parameters
-
LocationObject:
(Object
):- abstraction over current location
action
(String
) -POP
orPUSH
state
(?Object
) - current state of locationpathname
(String
) - pathname without query parameterssearch
(String
) - search part of path (query parameters as string)
Use this component whenever you want to render routes. This component needs store
to be accessible in context.
<View />
components can be nested, so you can use them in your own components (in case of nested routes)
<View /> // will render current route component (if route component renders <View /> too, it will render component of nested route
Use this component whenever you want an <a>
element to go to route. This component need store
to be accessible in context.
Internally this component is dispatching action transitionTo()
- Props:
to
(String
) - url pathname to go toquery
(?Object.<String, *>
) - optional, query parameters (will be add tohref
attribute)stateProps
(?Object.<String, Object.<String, *>>
) - properties foractive
,inactive
state of<Link/>
active
(?Object.<String, *>
) - optional props to be assigned if<Link/>
href
is active (matching current route)inactive
(?Object.<String, *>
) - optional props to be assigned if<Link/>
href
is inactive (not matching current route)