How to use react-router-redux with immutable.js
1. react-router-redux usage
react-router-redux is library created by React Community using for connecting react-router to redux.
react-router-redux
is easy to use. You need first import syncHistoryWithStore and routerReducer these two functions:
import {syncHistoryWithStore, routerReducer} from 'react-router-redux'
Then you have to define a routing property in store:
const store = createStore(
combineReducers({
...reducers,
routing: routerReducer
})
)
At last, create a history object, and pass it to Router:
import {Router, Route, browserHistory} from 'react-router'
const history = syncHistoryWithStore(browserHistory, store)
ReactDOM.render(
<Provider store={store}>
<Router history={history}>
<Route path="/" component={App}>
<Route path="foo" component={Foo}/>
<Route path="bar" component={Bar}/>
</Route>
</Router>
</Provider>,
document.getElementById('root')
)
If you need to navigate by redux action:
import {routerMiddleware, push} from 'react-router-redux'
const middleware = routerMiddleware(browserHistory)
const store = createStore(
reducers,
applyMiddleware(middleware)
)
function createFooAction() {
return push('/foo);
}
2. with immutable
In a word, react-router-redux
works fine with normal store's state. But if you use immutable.js to wrap state, you have to make some changes.
2.1. Your own custom routerReducer
See origin routerReducer definition. This object spread syntax need state be a pure JavaScript object. But an immutable map is not, so you have to redefine it:
import {Map} from 'immutable'
const routerReducerInitialState = new Map({'locationBeforeTransitions': null});
const immutableRouterReducer = (state = routerReducerInitialState, {type, payload}) => {
if (type === LOCATION_CHANGE) {
return state.set('locationBeforeTransitions', payload)
}
return state
}
2.2. Your own custom selectLocationState
selectLocationState function is an option of the 3rd parameter of syncHistoryWithStore. The default definition is:
const defaultSelectLocationState = state => state.routing
The key is visiting locationBeforeTransitions in state, so your redefine it:
const history = syncHistoryWithStore(browserHistory, store, {
selectLocationState: state => ({locationBeforeTransitions: state.routing.get('locationBeforeTransitions')})
})
Notice: as combineReducer creates a pure JavaScript object always, the topmost level of state is NOT an immutable object, so you state.routing not state.get('routing').