Try   HackMD

Exploration of useUrlParams()

What we would like:

const UrlCounter = component$(() => { const params = useUrlParams({ count: 0 }); return ( <button onClick$={() => params.count++}> {params.count} </button> ); });

so the above should result in something like http://localhost/?count=123

useUrlParams() implementation

function useUrlParams<T>(initial: T): T { const params = useStore({count: 123}); useWatch$((track) => { track(params); // put code to update `location.search` }); useClientEffect$(() => { // code to listen to the `location.search` change }, {run: 'load'}) }

The above is the basic idea. However, the above has an issue, that it will always return a new instance of the params, where as we should have a way to return the same instance no matter how many times it is invoked.

New API proposal:

Obvious, but wrong

For that reason we should have a way to scope the useStore()

const params = useStore({count: 123}, {scope: 'container'});

The proposal is to add additional parameter to the useStore which will ensure that the value it returns is scoped to the container. This in effect makes the params a singleton within the application.

The above is not ideal, because the same issue applies to all of the use method.

useWith()

function useUrlParams<T>(initial: T): T { useWith('container', () => { const params = useStore({count: 123}); useWatch$((track) => { track(params); // put code to update `location.search` }); useClientEffect$(() => { // code to listen to the `location.search` change }, {run: 'load'}) }); }

Having useWith would allow to re-scope the location of the binding code. Namely to a different element or to the container.

New API for listening on location changes