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.
59 lines
1.8 KiB
JavaScript
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;
|