useQueryParams hook returns stale values when going back in history
See original GitHub issueHello, it’s me again 👋
So it seems that the latest changes introduced for useLocationChange
have caused a problem with other hooks using it (not exactly sure why though).
When using useQueryParams
, the URL param values returned when going back in history (web browser back button) do not reflect the current window location parameters, they are behind (stale).
I reverted to raviger
0.5.9
and the problem disappeared.
Would you have any idea what could cause that? If that’s too vague I can work on building a reproduction somewhere, let me know.
Issue Analytics
- State:
- Created 4 years ago
- Comments:9 (9 by maintainers)
Top Results From Across the Web
ReactRouterRoute breaks with React Router v6 #108 - GitHub
I have multiple nested useQueryParams in my app (parent and children will both be modifying different query params simultaneously) and I cannot get...
Read more >Hooks to persist state in the query string or history.state in React
Introducing: useQueryState() The default value will be returned as the current value, as long as the value was not updated and the query...
Read more >useQuery | TanStack Query Docs
The time in milliseconds after data is considered stale. This value only applies to the hook it is defined on. If set to...
Read more >react-router-query-params-hook - npm package - Snyk
First you have to create your actual useQueryParams hook. react-router only returns a string for location.search , though you have to provide ...
Read more >Be Aware of Stale Closures when Using React Hooks
The stale closures is a pitfall of React hooks when an outdated variable is captured by a closure.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
After more than an hour trying to debug the issue (and it’s now 11.30pm here in Sydney hehe) I think I have found the reason for the bug.
useRoutes
will always be used in a parent component of any component that themselves useuseQueryParams
orusePath
.useRoutes
usesuseLocationChange
here.If you comment out the
useLocationChange
usage inuseRoutes
, the bug disappears.This is because whenever the
popstate
event is triggered, it will be fired on the event listeners in the order they were registered, hence the component usinguseRoutes
will receive it first. That component will re-render, causing the children component using the other two hooks to re-render too. This is happening synchronously, before the children hooks get a chance to receive their ownpopstate
event.But since the
useQueryParams
hook does not keep a stable reference to the callback it passes touseLocationChange
, the render loop being called on that component will cause a new callback to be passed, and theuseEffect
to trigger its clean up effect, which will unbind thepopstate
listener.So when the event loop has finished the render and goes back to firing the remaining
popstate
event to the other listeners, theuseQueryParams
listener has already been unbound, and thus will not be triggered.Now, what I am not clear about is why going forward in history is fine… And I’ll rather go to bed than investigate that!
Try
raviger@rc
orraviger@1.0.0-rc.3
and let me know