history
history copied to clipboard
Run async side effects before url change
This issue might sound like an anti pattern but the idea is only to implement standard browser behaviour.
Generally, in a non SPA app, when user clicks an A tag the browser waits for the response in the background and does not update the url before response arrives (or fails after timeout). In SPA apps the general pattern is to update the url and then rerender, fetch data etc. based on the url. While this is ok most of the time it creates new problems like
- If your SPA triggers on url change. You will probably render some sort of loading state directly on url change, this is most of the time annoying and unncessary
- Tracking (and other tools) that listens to url change will trigger before data has arrived. For example google analytics
Generally I'm looking for a solution to run a side effect (like fetching data) before transition is made. This way we can implement something similar to browser behaviour and ensure that needed data is in place when actual url change is made.
Of course you could implement this in your app (like react) but I think that history is a good place for such a logic, mostly because it is already standard behaviour in browsers
I would be happy to contribute to this feature if we find it meaningful
I believe that this would require a major re-implementation of the library. I did a similar thing with hickory and it works nicely, but comes with caveats. The complication is because if the navigation isn't instant, then it needs to be cancellable (the user may click another link while the current one's async actions are running).
Yes it might not work with current api but i was planning to add it as an optional thing in the transitionmanager. It is already callback based so it might support this. But of course there will be complications
Regarding new url during async work that could be managed as well I think
I opened this issue to see if there is any interest in this problem or any other good solutions
Your package looks nice, I was thinking about writing my own with the same api as history to make it a drop in replacement but if more people want this feature in the history package it would be good to land it there instead
This is a great feature to add in v6, I think. It's tricky though because we don't always have control of when the new URL appears in the address bar. In the case of a PUSH
or REPLACE
we do (we are changing the URL), but not on a POP
(the URL has already changed).
can't we use the transition manager instance for that?
I will also happily contribute for that feature. Will make my life easier :)
In a previous issue, it was pointed out that a pre-configured custom history object could be passed to a Router component, rather than using a BrowserRouter component.
Here's a way you might be able to use this to accomplish what you want, using the current version of React Router.
- Wrap the original
history
object such that you intercept calls topush
. - Pass the wrapped history object to Router, and use Router instead of BrowserRouter.
- When push is called, store the destination URL in a "transitioningTo" variable somewhere.
- Perform any async requests. You probably want to show a spinner or otherwise tell the user to wait while this is happening.
- Call the original, wrapped
history.push
when the async requests are completed.
This doesn't solve history.pop
or page refreshes, so you would still need to have a page that looks reasonable if the user navigates to it directly before the async requests are completed.