import React, { useMemo, useRef, useState } from 'react'; import { Select, Spin } from 'antd'; import type { SelectProps } from 'antd'; import debounce from 'lodash/debounce'; export interface DebounceSelectProps extends Omit, 'options' | 'children'> { fetchOptions: (search: string) => Promise; debounceTimeout?: number; } function DebounceSelect< ValueType extends { key?: string; label: React.ReactNode; value: string | number } = any, >({ fetchOptions, debounceTimeout = 800, ...props }: DebounceSelectProps) { const [fetching, setFetching] = useState(false); const [options, setOptions] = useState([]); const fetchRef = useRef(0); const debounceFetcher = useMemo(() => { const loadOptions = (value: string) => { fetchRef.current += 1; const fetchId = fetchRef.current; setOptions([]); setFetching(true); fetchOptions(value).then((newOptions) => { if (fetchId !== fetchRef.current) { // for fetch callback order return; } setOptions(newOptions); setFetching(false); }); }; return debounce(loadOptions, debounceTimeout); }, [fetchOptions, debounceTimeout]); return (