import { useState, useMemo, useRef, useEffect } from 'react';
import _ from 'lodash';
function useFetchDebounceSelect ({
api,
keywordName = 'search',
otherParams = {},
transformKeys = {},
debounceTimeout = 1000,
relationParams = {},
}) {
const [fetching, setFetching] = useState(false);
const fetchRef = useRef(0);
useEffect(() => {
debounceFetcher('', relationParams);
},[relationParams?.value])
const [list, setList] = useState([])
const debounceFetcher = useMemo(() => {
const loadOptions = (value, relationParams) => {
fetchRef.current += 1;
const fetchId = fetchRef.current;
setList([]);
setFetching(true);
const params = {
page: 1,
rows: 20,
[keywordName]: value,
...otherParams,
}
if (relationParams?.key) {
params[relationParams.key] = relationParams.value;
}
api(params).then((newOptions) => {
if (fetchId !== fetchRef.current) {
return;
}
setList(newOptions.data.list);
setFetching(false);
});
};
return _.debounce(loadOptions, debounceTimeout);
}, [debounceTimeout]);
const getOtherData = (item) => {
let otherData = {}
if (transformKeys?.other?.length) {
transformKeys.other.map(key => {
otherData[key] = item[key];
})
}
return otherData;
}
return {
type: 'select',
options: list.map(item => {
const otherData = getOtherData(item)
return {
label: item[transformKeys.label],
value: item[transformKeys.value],
...otherData,
}
}),
other: {
placeholder:'请选择'
labelInValue:true,
filterOption: false,
showSearch: true,
loading: fetching,
onSearch: (v) => debounceFetcher(v),
}
}
}
export default useFetchDebounceSelect;
import useFetchDebounceSelect from './useFetchDebounceSelect'
import { url } from '@/api'
function useFetchxxxList () {
return useFetchDebounceSelect({
api:url,
keywordName:'name',
transformKeys:{
label:'name',
value:'id',
}
})
};
export default useFetchxxxList;
import useFetchxxxList from '@/hooks/useFetchxxxList';
import { Select } from 'antd'
export default function() {
const { other, options } = useFetchxxxList();
return (
<Select {...other} name="xxx" >
{options.map(({value, label}) => <Option key={value} value={value}>{label}</Option>))}
</Select>
)
}