React: Could not find router reducer in state tree, it must be mounted under “router”
Aron Schüler Published
As I was upgrading dependencies for an older project, I ran into the error Could not find router reducer in state tree, it must be mounted under "router"
and spent a good amount of time trying to find a solution. Multiple stackoverflow posts were solved by upgrading the history
package, but this was not what caused it for me. My project used the connected-react-router package. I migrated this package from major version 4 to major version 6. If you did this as well and now get the following error, I can help you!
Fixing the reducer
As the error suggests, we have a problem with our router reducer. This happens because the redux
api changed and it expects a router in your applications call to combineReducers
. So, to solve this error, we have to adapt our call to that function. It can be found most-likely in a reducers.js
file somewhere in your project.
Importing connectRouter into the reducer.js
First, we have to add the following line to the imports in reducers.js
:
Change reducer signature to accept parameter
Next, we have to modify our root reducers signature. In version 4.x, the reducer took no arguments. In the major versions above, we need the history
argument. So change your export from something like export default combineReducers({...})
to:
Add router argument to combineReducers call
As the combineReducers function of redux
expects a router argument, we have to add that named argument to our call and connect to our router there:
This was the final modification of our reducers.js
file. Now, we have to switch to the file that configures and creates our redux store. Most likely, this should be configureStore.js
.
Use adapted function in createStore in configureStore.js
Adapt imports
First, we need to change our imports. We don’t want to connect to the router in configureStore.js
anymore, as we already do this in our reducer now. So, remove the import of connectRouter
:
Next, we should modify the name under which the default export of reducers.js
is imported. I propose some name that uses the imperative, as an indicator what the function does:
Use createRootReducer in createStore redux store creation
As a final step, we have to adapt the way we connect to our router. While it used to be something like connectRouter(history)(rootReducer)
we want the createStore
function now to be something like:
Done!
Now your application should render again. If it does not, leave your error message in the comments and we’ll figure out a solution together.
If you want to read more tutorials like this, be sure to check out my other JavaScript fixes!