Reloading causes "Warning: You cannot PUSH the same path using hash history" with react-router-redux #121
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
MichaelContento/redux-storage#121
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This is a bug that arises from using popular packages together. I'm posting the bug here, and hoping you can cooperate with the involved parties.
If a user reloads an app that uses redux-storage & redux-storage-engine-localstorage & react-router & react-router-redux then the app will eventually complain with the error
Warning: You cannot PUSH the same path using hash history.Cause: React-storage triggers react-router-redux's enhanced react-router history, since it's causing a change in state. This in turns causes a
history.push(...)to the restored URL, which is the same since it's a reload of the same page, thus causing the warning.This issue doesn't seem to be directly addressed in the other projects since it's caused by using this plugin which automatically loads router state. Note that loading the state before enhanced router will avoid this bug, but then redux-storage fails to restore previous state on the second reload.
hi have you managed to fix this error? I'm rolling my own state serialise and deserialise but sounds like the same issue.
Sorry, I did not find an exact fix. In your case, when writing your own serializer, you can make explicit exceptions to what gets saved and loaded. I'd consider it somewhat of a hack but simply ignoring restoring URL would be a way to make it work if you're already at the URL.
@scarlac thats exactly what I have in mind. but feels like I'm attempting to fix something that someone else has fixed more elegantly. I've still got the warning, might come back to it on a rainy day.
Maybe I don't understand the problem properly .. but .. well, it sounds like redux-storage-decorator-filter could be the missing piece!?
Unfortunately I don't think so @michaelcontento. It's a "orchestration" issue that follows from blindly restoring state to all components. I do have to say that I am not sure there's an easy fix.
Here's more verbose use-case-like explaination:
/mysite. Browser finishes loading./mysite/dashboard3a. react-router calls
setStatewithcurrentUrl: "/mysite/dashboard"which triggers an internal process that then callshistory.push(this.state.currentUrl).3b. Redux-storage is subscribed to state updates and is thus triggered to save current state, including state of react-router which contain current URL, now
/mysite/dashboard./mysite/dashboard...4a. react-router(-redux) initializes with a store-synched history
4b. redux-storage initializes, reads from storage and restores
currentUrlto/mysite/dashboardwhich causes a state change trigger...4c. react-router is then re-rendered with the new state object because of react-router-redux's synched hsitory, but the same
currentUrlas browser is already on which causes it to log a warning since browser is already at that URL.If there was a way to inject a small piece of code into redux-storage to prevent it from restoring certain parts of the global state, using a callback, that would be a possible solution. The filter decorator is some of the fix, but you don't always want to ignore the values - only in the case where
state.currentUrl == location.href.toString()-ish. But maybe it could be patched to do it?I'm not sure if it's a good idea to persist
currentUrlat all. What's the benefit of doing so?Maybe I'm wrong but event at the earliest point possible (read: where you construct all the required objects (redux, redux-storage, react-router, ...) after a full reload) the destination url (=
currentUrl) is already determined.The loaded
currentUrlcould only be different if the user changes the address bar and hits enter. This would causereact-routerto render/changed/by/userand, after redux-storage has received the old state from the engine, a re-render with/loaded/from/old/state. Is this even a desired behaviour?But even IF this is a desired behaviour - use a custom merger! 😄
A merger is passed as second argument to
storage.reducerand is responsible for properly mergingcurrentStatewithloadedState. So this is exactly the point where you could perform thestate.currentUrl == location.href.toString()comparison.I think it's realistic to assume that cherry-picking from react-router(-redux) state can cause some pretty exotic bugs that you can't issue reports for. One of the proposed features of using react-router-redux is that when your location is a part of the store, you can work with the time machine debugger, etc.
But! I didn't see the custom merger stuff! That could very well be the solution 👍
Perhaps someone will make a PR for documentation of
storage.reducerahem