forked from 47ng/nuqs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuseQueryStates.ts
39 lines (31 loc) · 1.31 KB
/
useQueryStates.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import { useRouter } from "next/router";
import { Options, optionsDefaults, Serializers } from "./defs";
export type UseQueryStatesKeysMap<T> = {
[K in keyof T]: Serializers<T[K]>;
};
export type Values<T> = {
[K in keyof T]: T[K] | null;
};
export type UpdatedValues<T> = {
[K in keyof T]: T[K];
};
export type SetValues<T> = (updatedValues: UpdatedValues<T>) => Promise<boolean>;
export type UseQueryStatesReturn<T> = [Values<T>, SetValues<T>];
export function useQueryStates<T extends { [key: string]: any }>(
queries: UseQueryStatesKeysMap<T>,
{ history }: Options = optionsDefaults
): UseQueryStatesReturn<T> {
const router = useRouter();
const getValue = (key: string) => (router.query[key] ? (router.query[key] as string) : null); // todo: not handling lists yet
const setQueryStates = (updatedParams: UpdatedValues<T>) => {
Object.keys(updatedParams).forEach((key: keyof Values<T>) => {
router.query[key as string] = queries[key].serialize(updatedParams[key]);
});
return history === "replace" ? router.replace(router) : router.push(router);
};
const values = Object.keys(queries).reduce((queryStates, key) => {
const value = getValue(key);
return { ...queryStates, [key]: value ? queries[key].parse(value) : null };
}, {}) as Values<T>;
return [values, setQueryStates];
}