Recoil icon indicating copy to clipboard operation
Recoil copied to clipboard

`urlSyncEffect` not syncing after an external url change

Open nichita-pasecinic opened this issue 2 years ago • 4 comments

If using urlSyncEffect effect I assume that any mutation to recoil atom would change the url (In may case just a query param key), but as well in case of a navigation from client side with a link, or useNavigate would update the atom value

const navigate = useNavigate();
navigate('/something'); // <-- removes the current query params (linked with recoil atom), but does not reset them 

nichita-pasecinic avatar Aug 19 '22 08:08 nichita-pasecinic

Are there any ways I could remove the queryParam from the url bar and have the atom being reset to the default state ?

nichita-pasecinic avatar Aug 19 '22 08:08 nichita-pasecinic

Recoil Sync attempts to sync bidirectionally, so changing an atom will update the URL and changing the URL will update the atom. (Note #1900 which may also be related to your issue, though that is fixable) It relies on subscribing to the browser popstate event for URL changes. This covered the usecase of using the Browser "back" button which was our priority. However, it appears this event is not triggered with all forms of navigation. There are also a hashchange event, but I think someone tried testing with that without much luck. I'm going to assume by useNavigate() you are referencing React Router. I don't know their internals, but assume they are using history.replace(); or history.pushstate();. As a workaround some have either manually triggered the popstate event or make extra history.pushstate(); history.popstate(); calls. Another solution might be to update the URL sync logic with polling, if someone wanted to add that.

drarmstr avatar Aug 19 '22 18:08 drarmstr

@drarmstr https://github.com/remix-run/history/blob/dev/packages/history/index.ts

Maybe recoil URL sync could use well-tested history wrapper: npm "history" package (from the team of react-router)

salvoravida avatar Sep 16 '22 00:09 salvoravida

@salvoravida Looking at the source of history package it looks like they also just rely on the popstate and hashchange events. I can add the hashchange event for more coverage. Though, I did actually manually test out some external URL changes and found even with just popstate it was working with relative links with href that changed either the search params or anchor hash and a button that changed location.hash with Chrome at least. Not sure what mechanism useNavigate() uses.

https://codesandbox.io/s/heuristic-elion-suen5c?file=/src/App.tsx

drarmstr avatar Sep 17 '22 02:09 drarmstr