diff --git a/core/screens/search/typesense/SearchTextInput.tsx b/core/screens/search/typesense/SearchTextInput.tsx index 587a4b9ee840fb7c6a80f528a431e53f6ec2acfd..0e4d26dfd9b2a1fb576a5f6ec7a2b3ae64c195cd 100644 --- a/core/screens/search/typesense/SearchTextInput.tsx +++ b/core/screens/search/typesense/SearchTextInput.tsx @@ -1,6 +1,7 @@ import { CloseCircleFilled, Search } from '@holi/icons/src/generated' import { HoliIcon } from '@holi/icons/src/HoliIcon' import HoliTextInput from '@holi/ui/components/molecules/HoliTextInput' +import { useDebounce } from '@holi/ui/helper' import React, { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { useSearchBox } from 'react-instantsearch-core' @@ -15,7 +16,10 @@ interface SearchBoxProps { export function SearchTextInput({ initialQuery, onQueryChange, props }: SearchBoxProps) { const { t } = useTranslation() - const { query, refine } = useSearchBox(props) + // Debouncing search requests as suggested on + // https://www.algolia.com/doc/guides/building-search-ui/going-further/improve-performance/js/#debouncing + const queryHook = useDebounce((query, refine) => refine(query), 300) + const { query, refine } = useSearchBox({ ...props, queryHook }) const [inputValue, setInputValue] = useState(query) const inputRef = useRef<TextInput>(null) @@ -33,16 +37,6 @@ export function SearchTextInput({ initialQuery, onQueryChange, props }: SearchBo // eslint-disable-next-line react-hooks/exhaustive-deps }, []) - // Track when the InstantSearch query changes to synchronize it with the React state. - useEffect(() => { - // We bypass the state update if the input is focused to avoid concurrent updates when typing. - if (query !== inputValue && !inputRef.current?.isFocused()) { - setInputValue(query) - } - // We don't want to track when the React state value changes. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [query]) - return ( <HoliTextInput aria-label={t('search.typesense.input.label')} diff --git a/core/screens/search/typesense/__tests__/SearchTextInput.test.tsx b/core/screens/search/typesense/__tests__/SearchTextInput.test.tsx index c1167e6e99383eeb8dd28d73f2090b7f505b7017..27b5c6349deefac17119ab51ee9e73eb6a9d81de 100644 --- a/core/screens/search/typesense/__tests__/SearchTextInput.test.tsx +++ b/core/screens/search/typesense/__tests__/SearchTextInput.test.tsx @@ -7,6 +7,7 @@ const mockUseSearchBox = useSearchBox as jest.MockedFunction<typeof useSearchBox jest.mock('react-instantsearch-core', () => ({ useSearchBox: jest.fn(), })) +jest.useFakeTimers() describe('SearchTextInput', () => { const mockRefine = (query = '') => {