A pure Redux-based, lightweight router.
npm i redux-router-lite
(Make sure your project has redux
installed).
- Purely Redux based. No React dependencies (but it's really easy to integrate with React).
- Easy to configure, just a single JSON object to define routes, in a common syntax.
- Listens to URL changes and updates the redux state accordingly.
- It uses route names to change the URL, allowing to change a route URL with minimal effort.
- It's fully compatible with Redux devtools time travel (It changes the URL too!)
{
"mode": "browser", // history mode, can be 'hash' or 'browser'
"routes": [
{ "name": "homePage", "path": "/" },
{ "name": "about", "path": "/about" },
{ "name": "user", "path": "/user/:id" },
],
"notFoundRoute": { "name": "notFound", "path": "/404" }
}
- mode the history type. Can be 'hash' or 'browser' (default: 'browser')
- routes an array of objects representing the routes.
- name the route unique name
- path the route path pattern
- notFoundRoute the route to redirect to, if no route is matched
The path can contain parameters, following the path-to-regexp syntax. Some example:
/user/:id
/user/616
⇒{ route: 'user', params: { id: '616'} }
/user
⇒ no match
/pictures/:viewMode?
/pictures/list
⇒{ route: 'pictures', params: { viewMode: 'list'} }
/pictures
⇒{ route: 'pictures', params: { viewMode: ''} }
Use them to restrict a parameter to match a regular expression. E.g. to have the id parameter to be a sequence of numbers:
/user/:id(\\d+)
(Note the double-escaped backslashes)
/user/12
⇒{ route: 'user', params: { id: '12'} }
/user/abc
⇒ no match
Parameters with no name, the params key will be their position index. E.g.:
/coords/(\\d+)/(\\d+)
/coords/12/34
⇒{ route: 'coords', params: { '0': '12', '1': '34' } }
Use * for 0 or more repetitions
/users/:ids*
/users/john/jack/jim
⇒{ route: 'users', params: { 'ids': 'john/jack/jim' } }
/users
⇒{ route: 'users', params: { } }
Use + for 1 or more repetitions
/groupcall/:users+
/groupcall/john/jack/jim
⇒{ route: 'groupcall', params: { 'users': 'john/jack/jim' } }
/groupcall
⇒ no match
import { combineReducers } from 'redux';
import { routerReducer as router } from 'redux-router';
export default combineReducers({
router, // the default key is 'router'
});
The resulting state will be:
{
router: {
location: {...},
route: '...',
params: {...},
searchParams: {...},
}
}
Note that the state key must be router
. If for any reason you need to mount the router
state to a different path, you must use the setRouterSelector
function, passing a selector
to the router state. E.g.
import { combineReducers } from 'redux';
import { routerReducer, setRouterSelector } from 'redux-router';
// needed to set up the custom router key(s)
setRouterSelector(state => state.one.two);
export default combineReducers({
one: combineReducers({
two: routerReducer,
}),
});
The resulting state will be:
{
one: {
two: {
location: {...},
route: '...',
params: {...},
searchParams: {...},
}
}
}
The routerConfig
function needs the Redux store and the JSON routes config object. E.g.:
import { createStore } from 'redux';
import rootReducer from 'app/reducer';
import { routerConfig } from 'redux-router';
// this can be defined elsewhere and imported
const routerConfig = {
routes: [
{ name: 'home', path: '/' },
],
notFoundRoute: { name: 'notFound', path: '/not-found' },
};
const store = createStore(rootReducer);
routerConfig(store, routerConfig);
Just create a React Component taking the route via props, and connect it to the state:
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { getRoute } from 'redux-router';
import showcase from 'react-showcase';
import LoginPage from 'ui/login/LoginPage';
import LoginForm from 'ui/login/LoginForm';
const MyRouter = ({ route }) => {
switch (id) {
case 'home': return <MyHomePage />;
case 'about': return <MyAboutPage />;
default: return <MyNotFoundPage />;
}
};
MyRouter.propTypes = {
route: PropTypes.string.isRequired,
};
const mapStateToProps = state => ({
route: getRoute(state),
});
export default connect(mapStateToProps, null)(MyRouter);
To redirect to a route programmatically (e.g. in response to an authentication error), the
gotoRoute
function must be used. E.g.:
import { gotoRoute } from 'redux-router';
// ... other code ...
// resulting URL: /user/72
gotoRoute('user', { id: '72' });
// resulting URL: /user/72?view=profile
gotoRoute('user', { id: '72' }, { view: 'profile' });