前言
由于接口返回较多,需要在Select组件中输入时进行调用接口并搜索,而不是初始化时把全部写入Option。
问题
当输入中文时,每打一个字母都会调用一次接口,想在中文输入完成,即点击空格后再进行接口调用
javascript
<Select
prefix={
<SearchOutlined
style={{
color: SearchOutlinedColor?.backgroundColor,
}}
/>
}
showSearch
value={orgValue}
placeholder={t('Input Search Text')}
style={{ width: 250 }}
defaultActiveFirstOption={false}
suffixIcon={null}
filterOption={false}
notFoundContent={null}
onSearch={handleOrgSearch}
onChange={handleOrgChange}
options={orgOptions}
onCompositionStart={handleCompositionStart} // 对中文的处理
onCompositionEnd={handleCompositionEnd}
allowClear
onClear={() => {
setOrgValue('');
onOrgSearch('');
setOrgOptions([]);
}}
size="small"
variant="filled"
/>
引入lodash.debounce
javascript
const [orgValue, setOrgValue] = useState();
const [orgOptions, setOrgOptions] = useState([]);
const [isComposing, setIsComposing] = useState(false);
const searchRef = useRef(null);
// 注册debouncedRef,输入结束后再进行接口调用
const debouncedFetchOrgData = useRef(
debounce((searchValue) => {
fetchOrgList(searchValue, setOrgOptions);
}, 500)
).current;
// 调用接口,获取列表,放入option中
const fetchOrgList = (value, callback) => {
selectCenterInfo({ name: value })
.then(result => {
if (result.length) {
const data = result.map((item) => ({
value: item.value,
label: `${item.label}(${item.value})`,
}));
callback(data);
} else {
callback([]);
}
})
.catch(err => {
console.log(err);
callback([]);
});
};
const handleOrgSearch = (newValue) => {
searchRef.current = newValue;
if (!isComposing) {
debouncedFetchOrgData(newValue);
};
};
const handleOrgChange = (newValue) => {
setOrgValue(newValue);
onOrgSearch(newValue); // 这是传入组件的props, 用来把选中的值传回父组件
};
const handleCompositionStart = () => {
setIsComposing(true);
};
const handleCompositionEnd = (e) => {
setIsComposing(false);
searchRef.current = e.target.value;
if (searchRef.current) {
fetchOrgList(searchRef.current, setOrgOptions);
}
};
useEffect(() => {
return () => {
debouncedFetchOrgData.cancel();
};
}, [debouncedFetchOrgData]);