diff --git a/frontend/src/components/Search/index.tsx b/frontend/src/components/Search/index.tsx index 5eb98ff7..6c3858fc 100644 --- a/frontend/src/components/Search/index.tsx +++ b/frontend/src/components/Search/index.tsx @@ -5,7 +5,7 @@ import { ComboboxOptions, } from "@headlessui/react"; import { useQuery } from "@tanstack/react-query"; -import { useDeferredValue, useEffect, useMemo, useRef, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { useNavigate } from "react-router-dom"; import { getSearchQuery } from "../../q"; import { search } from "../../icons/search"; @@ -17,6 +17,7 @@ import { SearchProviderResult } from "./ProviderResult"; import { SearchOtherResult } from "./OtherResult"; import { definitions } from "@/api"; import clsx from "clsx"; +import { useDebouncedValue } from "@/hooks/useDebouncedValue"; function getSearchResultType(value: string) { switch (value) { @@ -117,8 +118,8 @@ export function Search({ placeholder = "Search resources (Press / to focus)", }: SearchProps) { const [query, setQuery] = useState(""); - const deferredQuery = useDeferredValue(query); - const { data, isLoading } = useQuery(getSearchQuery(deferredQuery)); + const debouncedQuery = useDebouncedValue(query, 250); + const { data, isLoading } = useQuery(getSearchQuery(debouncedQuery)); const inputRef = useRef(null); const navigate = useNavigate(); diff --git a/frontend/src/hooks/useDebouncedValue.ts b/frontend/src/hooks/useDebouncedValue.ts new file mode 100644 index 00000000..b452d3a3 --- /dev/null +++ b/frontend/src/hooks/useDebouncedValue.ts @@ -0,0 +1,17 @@ +import { useEffect, useState } from "react"; + +export function useDebouncedValue(value: string, delay: number) { + const [debouncedValue, setDebouncedValue] = useState(value); + + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + return () => { + clearTimeout(handler); + }; + }, [value, delay]); + + return debouncedValue; +} diff --git a/frontend/src/q.ts b/frontend/src/q.ts index 3fe217b1..1ff78970 100644 --- a/frontend/src/q.ts +++ b/frontend/src/q.ts @@ -13,15 +13,7 @@ export const getSearchQuery = (query: string) => queryFn: query.length > 0 ? async ({ signal }) => { - // This is the lazy man's debounce, by waiting 100ms before making the request - // and utilizing the signal to cancel the request if the query changes - // we get a debounce effect - await (() => new Promise((resolve) => setTimeout(resolve, 100)))(); - if (signal.aborted) { - return; - } - - return await api(`search?q=${encodeURIComponent(query)}`, { + return api(`search?q=${encodeURIComponent(query)}`, { signal, }).json(); }