Skip to content

Instantly share code, notes, and snippets.

@kylecordes
Last active May 7, 2022 02:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kylecordes/89dcfaaada1d97f983e9363242957e23 to your computer and use it in GitHub Desktop.
Save kylecordes/89dcfaaada1d97f983e9363242957e23 to your computer and use it in GitHub Desktop.
Attempt at a Qwik useUrlParams
import {
useStore,
useWatch$,
useClientEffect$,
useServerMount$,
} from "@builder.io/qwik";
export const ranAlready = new Set<any>();
export function useUrlParams<STATE extends object>(initialState: STATE): STATE {
const params = useStore<STATE>(initialState);
useWatch$((track) => {
track(params);
if (!ranAlready.has(params)) {
// Skip first time - haven't had a chance to load the searchParams yet.
ranAlready.add(params);
return;
}
// put code to update `location.search`
const url = new URL(window.location.href);
for (const k in params) {
url.searchParams.set(k, (params as any)[k]);
}
window.history.pushState({}, "", url);
});
useClientEffect$(() => {
const url = new URL(window.location.href);
url.searchParams.forEach((v, k) => ((params as any)[k] = v));
// TODO listen to the `location.search` change, IF we want multiple
// instances of this mechanism to act as an implicit communication channel
});
useServerMount$(() => {
// This part not tested yet because I don't have a working SSR setup with current mainline yet.
const url = new URL(window.location.href);
url.searchParams.forEach((v, k) => ((params as any)[k] = v));
});
return params;
// TODO handle serializable non-strings in a way that roundtrips to the search
// params and gets the same types back; perhaps borrow from:
// https://github.com/pbeshai/use-query-params/blob/master/packages/serialize-query-params/src/serialize.ts
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment