41 lines
1.2 KiB
TypeScript
41 lines
1.2 KiB
TypeScript
import { useCallback } from "react";
|
|
import { useSearchParams } from "~/lib/router-compat.tsx";
|
|
|
|
/**
|
|
* 列表页筛选状态写进 URL query(docs/design/console-ia.md §3.6),刷新和分享链接不丢筛选。
|
|
* const f = useQueryState(["status", "managed"]);
|
|
* f.values.status; f.set("status", "paused"); f.reset();
|
|
*/
|
|
export function useQueryState<K extends string>(keys: readonly K[]) {
|
|
const [params, setParams] = useSearchParams();
|
|
const values = Object.fromEntries(keys.map((k) => [k, params.get(k) ?? ""])) as Record<K, string>;
|
|
const set = useCallback(
|
|
(key: K, value: string) =>
|
|
setParams(
|
|
(prev) => {
|
|
const next = new URLSearchParams(prev);
|
|
if (value) next.set(key, value);
|
|
else next.delete(key);
|
|
return next;
|
|
},
|
|
{ replace: true },
|
|
),
|
|
[setParams],
|
|
);
|
|
const keyList = keys.join(",");
|
|
const reset = useCallback(
|
|
() =>
|
|
setParams(
|
|
(prev) => {
|
|
const next = new URLSearchParams(prev);
|
|
for (const k of keyList.split(",")) next.delete(k);
|
|
return next;
|
|
},
|
|
{ replace: true },
|
|
),
|
|
[setParams, keyList],
|
|
);
|
|
const active = keys.some((k) => !!values[k]);
|
|
return { values, set, reset, active };
|
|
}
|