perf: 搜索选项框, 自动获取

main
Lei OT 6 months ago
parent 975c781be8
commit a68e32d807

@ -1,29 +1,41 @@
import React, { useMemo, useRef, useState } from 'react';
import React, { useMemo, useRef, useState, useEffect } from 'react';
import { Select, Spin } from 'antd';
import { debounce, objectMapper } from '@/utils/commons';
function DebounceSelect({ fetchOptions, debounceTimeout = 800, ...props }) {
function DebounceSelect({ fetchOptions, debounceTimeout = 500, initLoad = false, defaultOptions=[], ...props }) {
const [fetching, setFetching] = useState(false);
const [options, setOptions] = useState([]);
const fetchRef = useRef(0);
//
useEffect(() => {
setOptions(defaultOptions);
if (initLoad && defaultOptions.length===0) {
loadOptions(' ');
}
}, [initLoad]);
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);
props.onFetch && props.onFetch(mapperOptions);
});
};
const debounceFetcher = useMemo(() => {
const loadOptions = (value) => {
fetchRef.current += 1;
const fetchId = fetchRef.current;
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);
});
};
return debounce(loadOptions, debounceTimeout);
}, [fetchOptions, debounceTimeout]);
return (
<Select
labelInValue
@ -32,7 +44,8 @@ function DebounceSelect({ fetchOptions, debounceTimeout = 800, ...props }) {
allowClear
maxTagCount={1}
loading={fetching}
dropdownStyle={{width: '20rem'}}
// dropdownStyle={{width: '20rem'}}
styles={{ root: { width: 'min(20rem, 100%)' }, popup: { root: { width: '20rem' } } }}
{...props}
onSearch={debounceFetcher}
notFoundContent={fetching ? <Spin size='small' /> : null}

@ -4,6 +4,7 @@ import SearchInput from './SearchInput';
import { fetchJSON } from '@/utils/request';
import { HT_HOST } from '@/config';
import { useTranslation } from 'react-i18next';
import useFormStore from "@/stores/Form";
//
export const fetchVendorList = async (q) => {
@ -13,15 +14,19 @@ export const fetchVendorList = async (q) => {
const VendorSelector = ({ ...props }) => {
const { t } = useTranslation();
const [{ vendorList }, setCache] = useFormStore(state => [state.cache, state.setCache]);
return (
<>
<SearchInput
<SearchInput initLoad={true}
placeholder={t('products:Vendor')}
mode={'multiple'}
maxTagCount={0}
{...props}
fetchOptions={fetchVendorList}
map={{ travel_agency_name: 'label', travel_agency_id: 'value' }}
onFetch={(v) => setCache({ vendorList: v })}
defaultOptions={vendorList}
/>
</>
);

@ -7,6 +7,10 @@ export const useFormStore = create(
setFormValues: (values) => set((state) => ({ formValues: { ...state.formValues, ...values } })),
formValuesToSub: {},
setFormValuesToSub: (values) => set((state) => ({ formValuesToSub: { ...state.formValuesToSub, ...values } })),
cache: {},
setCache: (values) => set((state) => ({ cache: { ...state.cache, ...values } })),
}), { name: 'formStore' })
);
export default useFormStore;

Loading…
Cancel
Save