Connected-react-router: Uncaught TypeError: Cannot read property 'pathname' of undefined

Created on 24 May 2017  路  21Comments  路  Source: supasate/connected-react-router

This happens to me when using HMR (only after I chnage something I'm working on). Strange enough but this happend on any action

2017-05-24 18_18_09-mahjong backend_ player dashboard

I did not notice such behaviour with previous versions.

From package.json:

{
    "connected-react-router": "^4.2.1",
    "react-router": "^4.1.1",
    "react-router-dom": "^4.1.1",
}

Most helpful comment

The problem is you don't have router in your state when HMR patch applying. You should wrap your rootReducer into connectRouter function.

store.replaceReducer(nextRootReducer); // your code now (probably)

to:

store.replaceReducer(connectRouter(history)(nextRootReducer)); // how it should be done

All 21 comments

Could you inspect more whether which LOC causes that error and what's the value of state in your redux store?

I'm using hot modules replacement. The error does not appear before a hot module update happens. But if I edit source of some component and it hot updates, this happens.

Also looks like this exception is the cause why hmr does not work causing full page reload atm:

image

It's hard to trace what happens atm since hmr is broken.

I'm using "react-hot-loader": "^3.0.0-beta.6", and "webpack": "^2.5.1",

I'll try to provide more details if I'll be able to debug this.

        var _toJS = toJS(getIn(context.store.getState(), 'router.location')),
            pathnameInStore = _toJS.pathname, // Looks like this code causes this
            searchInStore = _toJS.search,
            hashInStore = _toJS.hash;
        // Extract history's location

When this happens _toJS = undefined

State:
2017-05-29 14_24_35-mahjong backend_ player dashboard

hmm, just before that I got a warning:

Unexpected key "router" found in previous state received by the reducer. Expected to find one of the known reducer keys instead: "form", [STRIPPED]. Unexpected keys will be ignored.

I just tried downgrading, seems like this is not related to the fact I did upgrade recently.
So my sentence

I did not notice such behaviour with previous versions.

makes no sence. I checked with previous versions of connected-react-router, react-router and react-router-dom, and the issue is still there.

Seems like router.location which is passed to somehow is not actual in some case. Cannot find out why. Issue is located here: https://github.com/supasate/connected-react-router/blob/master/src/ConnectedRouter.js#L32

That's interesting. Could you provide me a minimal repo that reproduces this problem? I'll try working on it then.

Well, that's not easy, I'll try to provide one later this week.

not sure if related but I was having similar if not identical error due to importing the wrong ConnectedRouter.

import { ConnectedRouter } from 'connected-react-router'
instead of
import { ConnectedRouter } from 'connected-react-router/immutable'

Thanks, @dimatter but that did not help. :(

The problem is you don't have router in your state when HMR patch applying. You should wrap your rootReducer into connectRouter function.

store.replaceReducer(nextRootReducer); // your code now (probably)

to:

store.replaceReducer(connectRouter(history)(nextRootReducer)); // how it should be done

@iceekey Thanks a lot! The seem very reasonable. I tried this and after quick check did not face my issue. I'll work with this for some time and will report later if the issue is completely resolved.

Seems like issue is resolved. Thanks, @iceekey

I am getting this issue in my environment, but the suggested solution is not working in my case:

This is my setup:

My codes

Store.js

import { applyMiddleware, createStore, compose } from 'redux';
import thunk from 'redux-thunk';
import { createBrowserHistory } from 'history'
import { connectRouter, routerMiddleware } from 'connected-react-router';

import rootReducer from '../Redux/Reducers/RootReducer';

export const History = createBrowserHistory();

const initialState = {};

const middleware = [
    routerMiddleware(history),
    thunk
];

const enhancers = [];

if (process.env.NODE_ENV === 'development') {
    enhancers.push(window.__REDUX_DEVTOOLS_EXTENSION__ && __REDUX_DEVTOOLS_EXTENSION__())
}

const Store = createStore(
    connectRouter(history)(rootReducer),
    initialState,
    compose(
        applyMiddleware(...middleware),
        ...enhancers
    )
);

export default Store;

App.js

import React from 'react';
import { render } from 'react-dom';
import { Route, Switch } from 'react-router';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'connected-react-router';

import Store, { History } from './Redux/Store';
import RaiseIssuePage from './Pages/Issue/New';
import HomePage from './Pages/Index';

const PageRoutes = () => (
<div id="PageRouters">
    <Switch>
    <Route exact path="/" component={HomePage} />
    <Route path="/issue/new" component={RaiseIssuePage} />
    </Switch>
</div>
);

class App extends React.Component {

render() {
    return (
    <Provider store={Store}>
        <ConnectedRouter history={History}>
            <PageRoutes />
        </ConnectedRouter>
    </Provider>
    );
}
}

render(<App />, document.getElementById('App'));

PageActions.js

import {INITIATE_PAGE } from '../Type';

export const initiatePage = (pageName) => (dispatch) => {
    console.log('initiatepageActions');
    dispatch({
        type: INITIATE_PAGE,
        payload: {pageName: pageName}
    });
}

PageReducer.js

import { INITIATE_PAGE } from '../Type';

const initialState = {
    pageName: '',
    issuePlace: {}
}

export default (state = initialState, action) => {
    switch (action.type) {
        case INITIATE_PAGE:
            const pageData = Object.assign({}, state, action.payload);
            return pageData;

        default:
            return state;
    }
}

RootReducer.js

import { combineReducers } from 'redux';
import PageReducer from './PageReducer';

export default combineReducers({
    page: PageReducer
});

Error

This is the error which I am getting:

screenshot from 2018-07-12 13-34-34

More info

In my HomePage component, I have a call on initiatePage which is available in PageAction.js. This is what clearly gives me this error and then what I get a blank page in the browser. When commenting out this line, everything went smooth, leaving a couple of warning messages which are pretty much same which you can see in the image above.

The error indication is exactly the same as the original thread, but the suggested solution by @iceekey is not working in my case (as you can see, I have already added it in my code).

I really lost here. Any help on this issue is really appreciated. Thank you.

+1

@progammer-rkt did you find a solution? Im having the same problem or similar problem, im getting Warning: Failed prop type: The prop action (and location) is marked as required in ConnectedRouter, but its value is undefined.

Ohh well, 3 hours later ... I had these problems because i use a custom immutableJS solution, ie my top reducers are not Immutable but their children are. So my state looks similar to this:

jsObjReducer = {
  imJsObject: Map()
}

So i access my state by doing state.jsObjReducer.get('imJsObject'); not state.getIn(['jsObjReducer', 'imJsObject']). And i had accidentally converted the router state to an immutable so when ConnectedRouter tried to access those vars by doing router.location it threw an error of course since my accidental conversion to ImJs obj before.

The provided solution for ImJs with connected-react-router doesnt work in my case because my top level reducers arent immutable (i dont use combineReducers from 'redux-immutable'; for my top level reducers, instead i use it from redux).
My solution was rather simple when i finally understood what went wrong, simply to not convert router state to immutable. I check if it is router

    let plain = JSON.parse(unescape(window.__INITIAL_STATE__));
    for (const key in plain) {
      if (key !== 'router') {
        initialState[key] = Immutable.fromJS(plain[key]);
      }
    }

@progammer-rkt

I found a typo in your store. You declare the const History like this : export const History = createBrowserHistory();
then use it like this routerMiddleware(history), and connectRouter(history)(rootReducer),. shouldn't it be this routerMiddleware(History), and connectRouter(History)(rootReducer), ?

```javascript



)} />
Miss
)} />



Replace the above code in index.js it will work

@progammer-rkt

Did you ever resolve this issue? I'm having very similar issue and very similar code.

image
image

can someone help me with the issue

image
image

can someone help me with the issue

I am getting the same code error as yours.

Did you fix the bug?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Not compatible with history v5?
Guymestef picture Guymestef  路  5Comments

Array in query params
nickvoronin-ellation picture nickvoronin-ellation  路  5Comments

You should not use <Route> outside a <Router>
austsinovich picture austsinovich  路  4Comments

<ConnectedRouter> imports <Router> from wrong module
alexseitsinger picture alexseitsinger  路  3Comments

Resetting state in v5.0.1
jjdp picture jjdp  路  4Comments