router-redux
v0.10.0
Published
transform route change as redux action.
Downloads
20
Readme
router-redux
View framework agnostic react-router-redux :)
- Make your Stateless component based development flow easy. work with these libraries.
- Adds pushState/popState based client-side routing to your project.
- Light weight(around 7K) but yet powerful router for Redux.
Demo: http://subuta.github.io/router-redux/
Installation
npm install router-redux --save
Example
First you need to pass routerReducer
to your own reducer
with routing
key.
// In reducers/index.js
import {combineReducers} from 'redux';
import {routerReducer} from 'router-redux';
const rootReducer = combineReducers({
routing: routerReducer // HERE
});
export default rootReducer;
Next you need to pass routerMiddleware
to your createStore
function.
Then create and export router
.
// In example/store.js
import createRouter, {routerMiddleware} from 'router-redux';
import reducer from './reducers/index.js';
const middlewares = [routerMiddleware];
const store = createStore(reducer, compose(
applyMiddleware(...middlewares)
));
export const router = createRouter(store);
Then router
enables you to pushState/popState based routing with redux.
// Get your exported router
import {router} from 'example/store.js';}
// Get router selector from router-redux
import {
getRouteError
} from 'router-redux';
// Register onError first (if you need to catch routing error)
router.onError(({state, dispatch}) => {
const routeError = getRouteError(state); // will extract error message from state.
console.log('routeError.message = ', routeError.message);
router.push('/error');
// You can navigate user to error page or call any other redux action.
dispatch(push('/error'));
});
// Called when user entered to path(/)
const onEnter = ({state}, cb) => {
console.log('[top]loading ...', state);
setTimeout(() => {
// User's navigation action will blocked untill `cb` called.
console.log('[top]timer fired');
cb();
// If you call `cb` with falsy value or Error object,
// Router-redux will emit router's onError. and stop routing to path(/).
// cb(new Error('[top]thrown error'));
}, 1000);
};
// Called when user leave from path(/)
const onLeave = ({state}) => {
console.log('[top]leave');
};
// Simple component to render.
const Top = () => {
return <h1>top</h1>;
};
router.on('/', <Top onEnter={onEnter} onLeave={onLeave}/>)
see example/components
for full example.
/react
-> example of React with JSX plugin./vidom
-> example of vidom plugin./snabbdom
-> example of snabbdom- other files are common redux files(
actions/reducers/store
)
Documentation
- API idea came from react-router-redux thanks!
routerMiddleware
router-redux's middleware function for redux.
You need to register it in your createStore
function.
// In store.js
import createRouter, {routerMiddleware} from 'router-redux';
import reducer from './reducers/index.js';
const middlewares = [routerMiddleware];
const store = createStore(reducer, compose(
applyMiddleware(...middlewares)
));
export const router = createRouter(store);
routerReducer()
router-redux's reducer function for redux.
You need to register it in your combineReducers
function.
// In reducers/index.js
import {combineReducers} from 'redux';
import {routerReducer} from 'router-redux';
const rootReducer = combineReducers({
routing: routerReducer // here
});
export default rootReducer;
createRouter(store)
When you import router-redux
, it gives you createRouter
,
You need to pass store
to routerCreator
, and it returns router
for later use.
export const router = createRouter(store)
Optionally you can pass history to createRouter like below.
import createHistory from 'history/createBrowserHistory'
const history = createHistory({basename: '/router-redux'});
export const router = createRouter(store, {history})
router
Will created by routerCreator
above.
router
will handle these basic router operation.
- register your render/onEnter/onLeave function to the router using
router.on(path, handler)
- navigate to other route using
router.push
and other history API based actionreplace/go/back/forward
router.on(path, handler)
- will register your render function to router.
path
can includespath parameter
like (/foo/:id) andpath
can be '*'(wildcard) for default route.handler
will accepts these value.router.on(path, {render, onEnter, onLeave})
-> is formal syntax.router.on(path, <Component onEnter={onEnter} onLeave={onLeave}/>)
-> is jsx version of formal syntaxrouter.on(path, fn)
-> will call passed function asrender
function.
- if current location matches passed
path
thenrouter.on
will call passedonEnter
as initial route.
onEnter(handler)
- If you specify
path parameter
to path,router-redux
will setroute
andparams
properties inroute
object(please referselectors
section). handler({state, dispatch}, [callback])
- Called when user navigated to
path
by pushState/popState or directly(by browser's url bar) - Handler will block routing until
callback
function is called. (This is useful for Authentication or Load page related data via ajax) - If you call
callback
function with falsy value(or Error object).router-redux
will callrouter.onError
and cancel navigation. (this is useful for handling un-authorized response or Server error) - If you omit
callback
function then your onEnter result will not affect to further navigation(become asynchronous). - If you navigate to
/foo/1
from/
, your state.routing inonEnter
function will looks like below.
| Key | Value |
|:-----------------------|:----------------------|
| current | current route (/
) |
| next | next route (/foo/1
) |
| last | previous route |
onLeave(handler)
handler({state, dispatch})
- Called when user navigated from
path
by pushState/popState - onLeave is called only user navigated from
path
afterinitialRouteResolved
, it means you need to bindonEnter
callback to use onLeave. - If you navigate to
/foo/1
from/
, Yourstate.routing
inonLeave
function will looks like below.
| Key | Value |
|:-----------------------|:----------------------|
| current | current route (/
) |
| next | null
|
| last | previous route |
router.onError(handler)
handler({state, dispatch})
- Called when routeError occurred in
router.onEnter
- You can get actual routeError using
getRouteError
selector.
router.render
router.render()
- After register your routes using
router.on(path, handler)
you need to callrouter.render
to render component based on current route(location). - if not route matches current location then router will render
*
route as a default route.
import {
inject,
router
} from 'example/store.js'
import {
getIsLoading
} from 'router-redux';
router.on('/', <Top onEnter={onEnter} onLeave={onLeave}/>)
const render = inject(({state}) => {
if (getIsLoading(state)) {
return <h1>loading ...</h1>
}
return router.render();
});
router.push(path)/router.replace(path)
- Create push/replace internal action with
path
. - When you call push/replace action. router'redux will call pushState/replaceState of history API
router.go(page)/router.back()/router.forward()
- Create go/back/forward internal action.
- When you dispatch go/back/forward action. router'redux will call go/back/forward of history API
selectors
- Will extracts value from your state. You can use selectors with reselect if you like.
route
has these properties- pathname(
String
):/foo/1 // path
- search(
String
):sample=true // Query param. you can use third-party library(https://github.com/ljharb/qs) to parse query.
- params(
Object
):{id: 1} // Matched params(declared in onEnter)
- route(
String
):/foo/:id // Matched route(declared in onEnter)
- pathname(
getCurrent(state)
- Extracts
current route
fromstate
getLast(state)
- Extracts
last route
fromstate
getNext(state)
- Extracts
next route
fromstate
getRouteError(state)
- Extracts
routeError
fromstate
routeError
becometrue
orError
(truthy value) when you call onEnter handler'scallback
with falsy value or Error object.
getIsLoading(state)
- Extracts
isLoading
fromstate
isLoading
becometrue
after onEnter called and until onEnter resolved(by callcb
).- This is useful to implement page loading animation.
Development
1. Clone this repo
git clone https://github.com/subuta/router-redux
cd ./router-redux
2. Install dependencies
- Caddy (Web server for Development)
- jspm@beta (For package management/build)
brew install caddy
npm install jspm@beta -g
npm i
jspm i
3. Run example app
caddy
# Open link.
open http://localhost:3000