Open camerondrysdale opened 2 years ago
Sure. I use it with a store being in react-hook-form
. Here's an example of watching an id
query param. I have a provider that updates useQueryParams via setId
when the form value changes. This particular component isn't utilizing it but I'll use default params to instantiate the form's store. I then hand over control to the form's store for the single source of truth, updating the query param as it changes.
export const IdFilterProvider = ({ children }: { children: ReactNode }) => {
const [id, setId] = useQueryParam(`id`, StringParam);
const methods = useForm({
defaultValues: {
id: id,
},
});
const { watch, setValue } = methods;
const idValue = watch(`id`);
const setIdValue = useCallback(
(v) => {
setValue(`id`, v);
},
[setValue]
);
useEffect(() => {
setId(idValue);
}, [idValue, setId]);
const context = useMemo(
() => ({
idValue,
setIdValue,
methods,
}),
[idValue, setIdValue, methods]
);
return <IdContext.Provider value={context}>{children}</IdContext.Provider>;
};
Since the query params in the url is the same, call the same useQueryParam
hook in each component is fine. You don't need to pass it all around.
Just call useQueryParam('latitude', withDefault(StringParam, ''));
in Sidebar.js
, Toolbar.js
and Content.js
. Or you can make a customized hook for it:
// hooks.js
export const useLatitudeParam = () => useQueryParam('latitude', withDefault(StringParam, ''));
export const useLongitudeParam = () => useQueryParam('longitude', withDefault(StringParam, ''));
export const useZoomParam = () => useQueryParam('zoom', withDefault(StringParam, ''));
// Content.js
import { useLatitudeParam, useLongitudeParam, useZoomParam } from './hooks';
const Content = props => {
// ...
const [latitude, setLatitude] = useLatitudeParam();
const [longitude, setLongitude] = useLongitudeParam();
const [zoom, setZoom] = useZoomParam();
// ...
return ...
}
also, you can use useQueryParams
instead:
// hooks.js
export const useMapParams = () => useQueryParams({
latitude: withDefault(StringParam, ''),
longitude: withDefault(StringParam, ''),
zoom: withDefault(StringParam, ''),
});
// Content.js
import { useMapParams } from './hooks';
const Content = props => {
// ...
// typeof mapParams = { }
const [mapParams, setMapParams] = useMapParams();
// ...
return ...
}
Is it possible to use this with a store like Zustand? https://github.com/pmndrs/zustand
This is because we have components like:
And then each of those has its own state and having to try and pass this up and down would be painful... so instead we use a store to have the state stored 'globally' but we want to use the query string to store this state as well.
For example:
But what we want to do is use something like the following (from our store):
And inside
useStore
we something like:So it'd be great if we could get the store to hook into useQueryParams or vice-versa. Does that seem possible?