README
redux-pages
A middleware-friendly routing helper that encapsulates raw URL paths.
"Parse once, route anywhere"
"Keep the state clean"
Features
- Full control from middlewares
- Raw URL paths is only used at definition
- Rich template syntax
redux-pages uses @ryo33/path-template.
Diagram
Page transitions are done in the flow as shown below.
Installation
$ npm install -S redux-pages
Example
Usage
import { createStore,
combineReducers, applyMiddleware } from 'redux'
import createHistory from 'history/createBrowserHistory'
import { createPages, createPagesReducer } from 'redux-pages'
// Define pages
const pages = createPages()
const indexPage = pages.addPage('/', 'index')
const postsPage = pages.addPage('/posts', 'posts')
const postPage = pages.addPage('/posts/:id', 'post')
const usersPage = pages.addPage('/users', 'users')
const userPage = pages.addPage('/users/:id', 'user')
const userPostPage = pages.addChildPage(
userPage, '/posts/:number', 'userPost',
{number: str => parseInt(str, 10)})
const errorPage = pages.addPage('/*', 'error')
const pageReducer = createPagesReducer(indexPage.name, {})
const reducer = combineReducers({
page: pageReducer
})
const pageSelector = state => state.page
const history = createHistory()
const getCurrentPath = () => history.location.pathname
const pushPath = (path) => history.push(path)
const pagesMiddleware = pages.middleware(pageSelector, getCurrentPath, pushPath)
const store = createStore(
reducer,
applyMiddleware(pagesMiddleware)
)
pages.handleNavigation(store, history.location.pathname)
history.listen((location, action) => {
pages.handleNavigation(store, location.pathname)
})
// Dispatch the action to change the page
store.dispatch(userPostPage.action({id: '5', number: 2}))
// history.location.pathname => '/users/5/posts/2'
// store.getState().page => {name: 'userPost', params: {id: '5', number: 2}}
// Change the path directly
history.push(userPage.path({id: '7'}))
// history.location.pathname => '/users/7'
// store.getState().page => {name: 'user', params: {id: '7'}}
// Go to the error page
history.push('/users/7/posts')
// history.location.pathname => '/users/7/posts'
// store.getState().page => {name: 'error', params: {}}
API
import {
createPages,
createPagesReducer,
changePage,
CHANGE_PAGE
} from 'redux-pages'
createPages() => pages
Creates a pages object.
pages
A pages object
pages.addPage(template, name, [mapperObject]) => page
Adds a page.
template
The URL path template Template Syntaxname
The name of the pagemapperObject
An object to map parsed params
[Example]
parsedParams:{id: '3', number: '5'}
mapperObject:{number: str => parseInt(str, 10)}
paramsForState:{id: '3', number: 5}
page
A page objectpage.name
The name of the pagepage.path([params])
Returns a path with the givenparams
page.action([params])
Returns a action with the givenparams
page.check(action)
({ type, payload }) => type === CHANGE_PAGE && payload.name === name
pages.addChildPage(page, template, name, [mapperObject]) => childPage
Adds a child page for the given page
.
pages.handleNavigation(store, pathname)
Handles a navigation event.
It matches the given pathname in order of addPage
/addChildPage
is called.
store
A storepathname
A pathname
pages.middleware(pageSelector, getCurrentPath, pushPath) => middleware
Changes the path when the middleware receives an changePage action.
pageSelector
A selector for the page stategetCurrentPath
A function to get the current pathpushPath
A function to push the path
createPagesReducer([name], [params]) => reducer
Create a reducer.
The state shape is {name, params}
.
name
params
The initial state
changePage(name, params) => action
Creates an action with given name and params.
action
{ type: CHANGE_PAGE, payload: {name: 'PAGE_NAME', params: PAGE_PARAMS}}
CHANGE_PAGE
The type of actions to change the page.
Author
Ryo Hashiguchi (Ryo33)
LICENSE
MIT