-
Notifications
You must be signed in to change notification settings - Fork 637
infinite loop with immutables #314
Description
My current setup includes react-router-redux@4.0.0 and immutable.js for managing my redux store.
To make react-router-redux work with immutables I setup up my routing reducer to wrap the shipped like
function routingWrapper(state, action) {
const immState = (typeof state !== 'undefined') ? state.toJS() : state;
return Imm.fromJS(routerReducer(immState, action));
}
and configured the syncHistoryWithStore
function with
const history = syncHistoryWithStore(hashHistory, store, {
selectLocationState: state => state.routing.toJS()
});
This seemed to work fine in the previous version and it worked also fine in v4 until I added an OnLeave
hook in my router that looks like
function cancelStatus(store) {
return () => store.dispatch(invalidateUser());
}
...
<Route path="/app" onLeave={cancelStatus(store)}>
...
This setup leads to an infinite dispatch of the invalidateUser action.
The only work-arounds I could come up until now are to exit the dispatching by writing
function cancelStatus(store) {
return () => setTimeout(() => store.dispatch(invalidateUser()), 0);
}
which is rather ugly or by making the routing subtree in my store a plain object instead of an immutable map.
Browsing through the source I feel the problem is located in handleStoreChange.
When I use state.routing.toJS()
in the selectLocationState
function a new object is created every time which makes the comparison on line 50 fail every time. As a consequence the history.transitionTo
function is called even if it wouldn't need to. Due to the dispatch in the onLeave
hook and the subsequent store update the handleStoreChange
subscription is called which again triggers history.transitionTo
due to the failing equality check.
Not sure what the best fix for this problem would be. Maybe a deep compare?