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 Free
Top 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

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.
useRouteswill always be used in a parent component of any component that themselves useuseQueryParamsorusePath.useRoutesusesuseLocationChangehere.If you comment out the
useLocationChangeusage inuseRoutes, the bug disappears.This is because whenever the
popstateevent is triggered, it will be fired on the event listeners in the order they were registered, hence the component usinguseRouteswill 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 ownpopstateevent.But since the
useQueryParamshook 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 theuseEffectto trigger its clean up effect, which will unbind thepopstatelistener.So when the event loop has finished the render and goes back to firing the remaining
popstateevent to the other listeners, theuseQueryParamslistener 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@rcorraviger@1.0.0-rc.3and let me know