You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
GHHub/src/components/SearchInput.jsx

59 lines
1.8 KiB
JavaScript

import React, { useMemo, useRef, useState, useEffect } from 'react';
import { Select, Spin } from 'antd';
import { debounce, objectMapper } from '@/utils/commons';
function DebounceSelect({ fetchOptions, debounceTimeout = 500, initLoad = false, defaultOptions=[], onFetch=null, ...props }) {
const [fetching, setFetching] = useState(false);
const [options, setOptions] = useState(defaultOptions);
const fetchRef = useRef(0);
// 首次加载获取选项
useEffect(() => {
if (defaultOptions.length!==0) setOptions(defaultOptions);
if (initLoad && defaultOptions.length===0) {
loadOptions(' ');
}
}, [initLoad, defaultOptions]);
const loadOptions = (value) => {
fetchRef.current += 1;
const fetchId = fetchRef.current;
if (value) setOptions([]);
setFetching(true);
fetchOptions(value).then((newOptions) => {
const mapperOptions = newOptions.map(ele => objectMapper(ele, props.map));
if (fetchId !== fetchRef.current) {
// for fetch callback order
return;
}
setOptions(mapperOptions);
setFetching(false);
onFetch && onFetch(mapperOptions);
});
};
const debounceFetcher = useMemo(() => {
return debounce(loadOptions, debounceTimeout);
}, [fetchOptions, debounceTimeout]);
return (
<Select
labelInValue
filterOption={false}
showSearch
allowClear
maxTagCount={1}
loading={fetching}
// dropdownStyle={{width: '20rem'}}
styles={{ root: { width: 'min(20rem, 100%)' }, popup: { root: { width: '20rem' } } }}
{...props}
onSearch={debounceFetcher}
notFoundContent={fetching ? <Spin size='small' /> : null}
optionFilterProp='label'
options={options}
/>
);
}
export default DebounceSelect;