Open nichita-pasecinic opened 2 years ago
Are there any ways I could remove the queryParam from the url bar and have the atom being reset to the default state ?
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 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 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
A workaround for react-router is to set a custom BrowserInterface:
const RecoilURLSyncJSONConfig: LocationOption = { part: "queryParams" };
<RecoilRoot>
<RecoilURLSyncJSON
location={RecoilURLSyncJSONConfig}
browserInterface={{
replaceURL: url => history.replace(url.replace(window.location.origin, "")),
pushURL: url => history.push(url.replace(window.location.origin, "")),
getURL: () =>
window.location.origin +
history.location.pathname +
history.location.search +
history.location.hash,
listenChangeURL: handler => {
const close = history.listen((_location, _action) => {
handler();
});
return () => {
close();
};
},
}}
>
<Router history={history}>
....
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, oruseNavigate
would update the atom value