hookrouter icon indicating copy to clipboard operation
hookrouter copied to clipboard

QueryParams ghosting on navigate

Open mitchellwarr opened this issue 5 years ago • 9 comments

If you got to route '/route?param=12'

navigate('/route', false, { param: 12 })

Then navigate back to '/'

navigate('/')

then navigate to 'route' using

navigate('/route')

at this point useQueryParams remembers the old param as if its ghost data.

however, when you navigate back using

navigate('/route', false, {})

everything is fine

Shouldn't navigate with an empty params object clear the queryParams given that the url has no params. There is a disconnect that the url has no params but useQueryParams still returns a param

mitchellwarr avatar Jul 03 '19 01:07 mitchellwarr

Same issue here ....

drabelo avatar Aug 09 '19 15:08 drabelo

@Paratron this is a big issue as state becomes inconsistent

asaf avatar Nov 08 '19 09:11 asaf

Hey there - I will take a look into it. Had very few spare time recently but am now back to fix some bugs and prepare v2 of hookrouter.

Paratron avatar Nov 08 '19 09:11 Paratron

@Paratron good to have you back!

I'm not sure this has anything to do with navigate,

the problem is that queryParams.js builds the queryParamObject only once and the only thing that can change queryParamsObject is setQueryParams

But URL may change (not only though navigate but through browser back/forward buttons as well), which will ghost previous queryParamObject even though url may not contain these query params any longer.

this could be solved by intercepting location.pathname and re-build the query params object whenever it changes.

Couldn't find a native way to do this, but submitted a PR with a tracking concept for a review

Thanks!

asaf avatar Nov 08 '19 10:11 asaf

You could have a useEffect that listens to pushState changes and then updates the queryParams state object as an override.

useEffect(
  () => {
    let cb = (...args) => update.current(...args);
    window.addEventListener("hashchange", cb, false);
    return () => {
      window.removeEventListener("hashchange", cb, false);
    }
  },
  []
)

This is a snippet from a hook I made for a locationHash hook. update.current is a ref callback function. The same idea should apply here right? Swap out hashchange with pushState listeners?

I'm sorry but I'm not in a position to test this or play around with it right now, so this is just theory

mitchellwarr avatar Nov 08 '19 20:11 mitchellwarr

@mitchellwarr ye i thought about it but I don't think that's gonna work because hashchange is only invoked when # is changed and I couldn't find an event listener for URL.pathname changes.

asaf avatar Nov 10 '19 06:11 asaf

@asaf I was about to comment with popstate, but it looks like you have it covered in this pr 👍

mitchellwarr avatar Nov 10 '19 19:11 mitchellwarr

@Paratron its been few months already, is this project dead?

asaf avatar Mar 04 '20 07:03 asaf

I have nearly zero free time to work on the project, but its not dead.

Paratron avatar Mar 04 '20 15:03 Paratron