import { useDebounceFn, useRequest } from 'ahooks';
import { Select } from 'antd';
import { useEffect, useState } from 'react';
type selectValues = string | string[] | undefined;
interface OptionStructure {
optionKey: string;
optionValue: string;
optionImgKey?: string;
}
interface IProps {
value?: selectValues;
onChange?: (value: selectValues) => void;
multiple: boolean;
showSearch: boolean;
pageSize: number;
resStructure: Record<'dataKey' | 'tokenKey', string>;
optionStructure: OptionStructure;
labelInValue: boolean;
placeholder: string;
fetch: any;
fetchFilter: (val: string) => string;
fetchBase: Record<string, any>;
reloadingControl?: {
reloading: boolean;
setReloading: (loading: boolean) => void;
};
}
const { Option } = Select;
function SelectTest(props: IProps) {
const {
placeholder,
multiple,
showSearch,
fetch,
pageSize,
resStructure,
optionStructure,
labelInValue,
fetchFilter,
fetchBase,
onChange,
reloadingControl,
value,
} = props;
const { reloading, setReloading } = reloadingControl!;
const { dataKey, tokenKey } = resStructure;
const { optionKey, optionValue, optionImgKey } = optionStructure;
const [options, setOptions] = useState<Record<string, any>[]>([]);
const [selectValue, setSelectValue] = useState(value);
const [pageToken, setPageToken] = useState('');
const [searchVal, setSearchVal] = useState('');
const [prevSearchVal, setPrevSearchVal] = useState('');
const [noMore, setNoMore] = useState(false);
const { run } = useRequest(fetch, {
manual: true,
onSuccess: (result: any) => {
const fetchData = result[dataKey];
const nextToken = result[tokenKey];
setOptions((originOptin) => {
return [...originOptin, ...fetchData];
});
if (!nextToken) {
setNoMore(true);
} else {
setPageToken(nextToken);
}
},
onError: () => {
//...
},
});
useEffect(() => {
setSelectValue(value);
}, [value]);
const handleScroll = (e: any) => {};
const handleClear = () => {};
const fetchOption = (val: string) => {
const filter = !!val
? {
filter: fetchFilter(val),
}
: {};
if (val !== prevSearchVal) {
//...
} else {
//...
}
};
useEffect(() => {
run({ pageSize, pageToken, ...fetchBase });
}, []);
useEffect(() => {
if (reloading) {
handleClear();
setReloading(false);
}
}, [reloading]);
const { run: handleSearch } = useDebounceFn(
(val) => {
if (!showSearch) return;
setSearchVal(val);
fetchOption(val);
},
{
wait: 800,
},
);
const Options = options.map((option) => {
return (
<Option value={option[optionValue]} key={option[optionValue]}>
{optionImgKey ? (
<img
src={option[optionImgKey]}
alt=''
style={{
width: '15px',
height: '15px',
borderRadius: '50%',
marginRight: '5px',
}}
/>
) : null}
{option[optionKey]}
</Option>
);
});
return (
<div>
<Select
labelInValue={labelInValue}
mode={multiple ? 'multiple' : undefined}
allowClear
showSearch={showSearch}
placeholder={placeholder}
filterOption={false}
onSearch={handleSearch}
onPopupScroll={handleScroll}
onChange={onChange}
onClear={handleClear}
value={selectValue}>
{Options}
</Select>
</div>
);
}
SelectTest.defaultProps = {
multiple: false,
showSearch: false,
pageSize: 10,
fetchBase: {},
fetchFilter: (val: any) => val,
reloadingControl: {
reloading: false,
setReloading: () => false,
},
labelInValue: false,
};
export default SelectTest;
对select进行组件封装
最新推荐文章于 2024-03-07 10:03:59 发布