REDUX
You can also use react-router-redux
which has goBack()
and push()
.
Here is a sampler pack for that:
In your app's entry point, you need ConnectedRouter
, and a sometimes tricky connection to hook up is the history
object. The Redux middleware listens to history changes:
import React from 'react'
import { render } from 'react-dom'
import { ApolloProvider } from 'react-apollo'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import client from './components/apolloClient'
import store, { history } from './store'
import Routes from './Routes'
import './index.css'
render(
<ApolloProvider client={client}>
<Provider store={store}>
<ConnectedRouter history={history}>
<Routes />
</ConnectedRouter>
</Provider>
</ApolloProvider>,
document.getElementById('root'),
)
I will show you a way to hook up the history
. Notice how the history is imported into the store and also exported as a singleton so it can be used in the app's entry point:
import { createStore, applyMiddleware, compose } from 'redux'
import { routerMiddleware } from 'react-router-redux'
import thunk from 'redux-thunk'
import createHistory from 'history/createBrowserHistory'
import rootReducer from './reducers'
export const history = createHistory()
const initialState = {}
const enhancers = []
const middleware = [thunk, routerMiddleware(history)]
if (process.env.NODE_ENV === 'development') {
const { devToolsExtension } = window
if (typeof devToolsExtension === 'function') {
enhancers.push(devToolsExtension())
}
}
const composedEnhancers = compose(applyMiddleware(...middleware), ...enhancers)
const store = createStore(rootReducer, initialState, composedEnhancers)
export default store
The above example block shows how to load the react-router-redux
middleware helpers which complete the setup process.
I think this next part is completely extra, but I will include it just in case someone in the future finds benefit:
import { combineReducers } from 'redux'
import { routerReducer as routing } from 'react-router-redux'
export default combineReducers({
routing, form,
})
I use routerReducer
all the time because it allows me to force reload Components that normally do not due to shouldComponentUpdate
. The obvious example is when you have a Nav Bar that is supposed to update when a user presses a NavLink
button. If you go down that road, you will learn that Redux's connect method uses shouldComponentUpdate
. With routerReducer
, you can use mapStateToProps
to map routing changes into the Nav Bar, and this will trigger it to update when the history object changes.
Like this:
const mapStateToProps = ({ routing }) => ({ routing })
export default connect(mapStateToProps)(Nav)
Forgive me while I add some extra keywords for people: if your component isn't updating properly, investigate shouldComponentUpdate
by removing the connect function and see if it fixes the problem. If so, pull in the routerReducer
and the component will update properly when the URL changes.
In closing, after doing all that, you can call goBack()
or push()
anytime you want!
Try it now in some random component:
- Import in
connect()
- You don't even need
mapStateToProps
or mapDispatchToProps
- Import in goBack and push from
react-router-redux
- Call
this.props.dispatch(goBack())
- Call
this.props.dispatch(push('/sandwich'))
- Experience positive emotion
If you need more sampling, check out: https://www.npmjs.com/package/react-router-redux