Connected React Router
A Redux binding for React Router v4
Main features
✨ Synchronize router state with redux store with uni-directional flow (history -> store -> router -> components).
🎁 Support React Router v4.
☀️ Support functional component hot reloading while preserving state (with react-hot-reload v3).
🎉 Dispatching history methods (push
, replace
, go
, goBack
, goForward
) work for both redux-thunk and redux-saga.
⛄️ Nested children can access routing state such as current location directly with react-redux
's connect
.
🕘 Support time traveling in Redux DevTools.
💎 Support Immutable.js
Installation
Using npm:
$ npm install --save connected-react-router
Or yarn:
$ yarn add connected-react-router
Usage
Step 1
- Create a
history
object. - Wrap the root reducer with
connectRouter
and supply thehistory
object to get a new root reducer. - Use
routerMiddleware(history)
if you want to dispatch history actions (ex. to change URL withpush('/path/to/somewhere')
).
......const history = const store =
Step 2
- Wrap your react-router v4 routing with
ConnectedRouter
and passhistory
object as a prop. - Place
ConnectedRouter
as children ofreact-redux
'sProvider
.
......ReactDOM
Now, it's ready to work!
Examples
See examples folder
FAQ
- How to navigate with Redux action
- How to get current browser location (URL)
- How to hot reload functional components
- How to hot reload reducers
- How to support Immutable.js
How to navigate with Redux action
with store.dispatch
store
in redux thunk
const login = { /* do something before redirection */ }
in redux saga
{ /* do something before redirection */ }
How to get current browser location (URL)
The current browser location can be accessed directry from the router state with react-redux
's connect
.
The location object composes of pathname, search (query string), and hash.
const Child = <div> Child receives <div> pathname: pathname </div> <div> search: search </div> <div> hash: hash </div> </div> const mapStateToProps = pathname: staterouterlocationpathname search: staterouterlocationsearch hash: staterouterlocationhash mapStateToPropsChild
How to hot reload functional components
- Separate main app component to another file.
App.js
const App = /* receive history object via props */<ConnectedRouter history=history><div><Switch><Route exact path="/" render= <div>Match</div> /><Route render= <div>Miss</div> /></Switch></div></ConnectedRouter>
- Wrap the
App
component withAppContainer
fromreact-hot-loader
v3 as a top-level container.
index.js
...const render = { // this function will be reused ReactDOM}
- Detect change and re-render with hot reload.
index.js
...if modulehotmodulehotaccept'./App' {/* For Webpack 2.xNeed to disable babel ES2015 modules transformation in .babelrcpresets: [["es2015", { "modules": false }]]*//* For Webpack 1.xconst NextApp = require('./App').defaultrenderWithHotReload(NextApp)*/}
Now, when you change any component that App
depends on, it will trigger hot reloading without losing redux state. Thanks react-hot-loader v3!
How to hot reload reducers
Detect change and replace with a new root reducer with router state
index.js
...if modulehotmodulehotaccept'./reducers' {/* For Webpack 2.xNeed to disable babel ES2015 modules transformation in .babelrcpresets: [["es2015", { "modules": false }]]*/store/* For Webpack 1.xconst nextRootReducer = require('./reducers').defaultstore.replaceReducer(connectRouter(history)(nextRootReducer))*/}
How to support Immutable.js
- Use
combineReducers
fromredux-immutable
to create the root reducer.
...const rootReducer = ...
- Import
ConnectedRouter
,routerMiddleware
, andconnectRouter
fromconnected-react-router/immutable
instead ofconnected-react-router
.
- (Optional) Initialize state with
Immutabel.Map()
...const initialState = Immutable...const store =
Build
npm run build
Generated files will be in lib
folder.
Contributors
See Contributors and Acknowledge.