1export function useDebouncedValue<T = any>(value: T, delay: number) {
2 const [isDebouncing, setIsDebouncing] = useState(false);
3 const [debouncedValue, setDebouncedValue] = useState<T>(value);
4
5 useEffect(() => {
6 setIsDebouncing(true);
7 const timer = setTimeout(() => {
8 setDebouncedValue(value);
9 setIsDebouncing(false);
10 }, delay);
11
12 return () => {
13 clearTimeout(timer);
14 };
15 }, [value, delay]);
16
17 return { debouncedValue, setDebouncedValue,isDebouncing };
18}
19
20
21import { useTransition, useState, useEffect } from "react";
22import { navigate, useLocation } from "rakkasjs";
23import { SearchType } from "./__generated__/SearchListQuery.graphql";
24
25export function useGithubSearch() {
26 const { current } = useLocation();
27 const initSearchType = current.searchParams.get("st") as SearchType | null;
28 const initSearchValue = current.searchParams.get("sq") ?? "";
29
30 const [, startTransition] = useTransition();
31 const { debouncedValue, setDebouncedValue, isDebouncing } = useDebouncedValue(
32 initSearchValue,
33 5000,
34 );
35 const [searchType, setSearchType] = useState<SearchType>(
36 initSearchType ?? "REPOSITORY",
37 );
38 useEffect(() => {
39 if (debouncedValue !== initSearchValue) {
40 setDebouncedValue(initSearchValue);
41 }
42 }, []);
43 useEffect(() => {
44 const new_url = new URL(current);
45 if (debouncedValue && debouncedValue !== initSearchValue) {
46 new_url.searchParams.set("sq", debouncedValue);
47 }
48 if (searchType && searchType !== initSearchType) {
49 new_url.searchParams.set("st", searchType);
50 }
51 startTransition(() => {
52 navigate(new_url.toString());
53 });
54 }, [debouncedValue, searchType]);
55
56 return {
57 debouncedValue,
58 setDebouncedValue,
59 isDebouncing,
60 searchType,
61 setSearchType,
62 startTransition,
63 current,
64 };
65}
66