acdlite / redux-router

Redux bindings for React Router – keep your router state inside your Redux store
MIT License
2.3k stars 216 forks source link

Infinite recursion when dispatching action in onEnter hook. #70

Open Furizaa opened 8 years ago

Furizaa commented 8 years ago

To initially fill the state of my app on the server, components subscribe to the onEnter hook of their routes. In this static initialisation functions I dispatch some actions.

Now this code in redux-router kicks in:

https://github.com/rackt/redux-router/blob/master/src/client.js#L29

... and replaces the history again (calling onEnter again) ...

https://github.com/rackt/redux-router/blob/master/src/client.js#L37

... because it didn't had the chance to set routerState which initially is set to undefined ...

https://github.com/rackt/redux-router/blob/master/src/client.js#L14

... resulting in an infinite loop.

Just setting routerState before the replaceHistory call fixes the loop - but everything still gets called twice.

store.subscribe(() => {
  const nextRouterState = routerStateSelector(store.getState());

  if (
    nextRouterState &&
    !routerStateEquals(routerState, nextRouterState)
  ) {
    const { state, pathname, query } = nextRouterState.location;
    routerState = nextRouterState;
    history.replaceState(state, pathname, query);
  } else {
    routerState = nextRouterState; 
  }
});

There has to be a way to initialise routerState with the correct state instead of undefined on the first call.

thom-nic commented 8 years ago

I'm seeing this issue, I originally commended on rackt/react-router#1977 thinking it was in react-router but it actually seems it's specific to redux-router. Here's a screenshot of what I see in my console:

JS console errors on HMR

Those XHRs in the log are called from action dispatches that are triggered from an onEnter defined in my route.

Scarysize commented 8 years ago

@Furizaa @thom-nic will reopen if this is still an issue.

phun-ky commented 8 years ago

I'm getting a similar issue with store.subscribe which makes it execute twice on a single pushState/replaceState.. We're using v1.0.0-beta6 with hot-middleware/connect

thom-nic commented 8 years ago

I moved away from use of onEnter to componentWillMount & componentWillUpdate in my page components which circumvented this issue. I don't know if onEnter still has an issue or not.

ghost commented 8 years ago

I still get this onEnter issue.

Scarysize commented 8 years ago

@srahulprdxn would mind providing us with a gist?

ghost commented 8 years ago

Yea sure. I'll post it soon.

ghost commented 8 years ago

@Scarysize I am almost writing the same code as @Furizaa . So you can consider his comment for reference. I cannot provide you with my gist as I have moved with another solution which is just a work around.

dentuzhik commented 7 years ago

I get infinite loop when trying to fire an action from history.listenBefore, and strangely enough it occurs only during HMR process. Not sure if this is the same problem, or different though. But seems it's the same, as described here: https://github.com/reactjs/react-router-redux/pull/30