react 组件之 searchSelect
·
下拉,搜索,接口搜索,配置化(初始化,非初始化),为空搜索,根据值搜索,loding,选项配置
-
支持用户输入时异步加载选项(带防抖)
-
可配置防抖时间
-
支持设置默认选项
-
可以控制是否在空值时加载数据
-
支持在组件挂载时加载初始数据
-
支持在聚焦时自动加载数据(当满足条件时)
-
data: 存储从异步请求获取的选项 -
value: 当前选中的值 -
loading: 加载状态 -
使用
useRef来存储当前搜索值(currentSearchRef)和定时器(timeoutRef) -
loadData(searchValue): 负责发起异步请求,使用防抖控制请求频率。在请求返回后,会检查当前搜索值是否与发起请求时一致,避免竞态条件。 -
handleSearch(newValue): 处理搜索输入变化,根据loadOnEmpty配置决定是否在空值时加载数据。 -
handleChange(newValue): 处理选择值变化。 -
使用
useEffect在组件挂载时执行初始加载(如果initialLoad为true),并在卸载时清除定时器。 -
防抖控制:有效减少请求次数,提升性能。
-
竞态处理:通过引用记录当前搜索值,避免因请求返回顺序导致的显示错误。
-
配置灵活:提供多个配置项(如
debounceTime、loadOnEmpty、initialLoad)满足不同场景需求。 -
内存管理:在组件卸载时清除定时器,避免内存泄漏。
-
空值处理:通过
loadOnEmpty控制空搜索时的行为,使组件更灵活。
import React, { useState, useEffect, useRef } from 'react';
import { Select } from 'antd';
const SearchSelect = (props) => {
const {
fetchData,
style,
placeholder,
defaultOptions = [],
debounceTime = 500,
loadOnEmpty = true, // 新增:是否在空值时加载数据
initialLoad = false // 新增:是否在组件挂载时加载初始数据
} = props;
const [data, setData] = useState([]);
const [value, setValue] = useState();
const [loading, setLoading] = useState(false);
const currentSearchRef = useRef();
const timeoutRef = useRef();
// 加载数据函数
const loadData = (searchValue) => {
// 记录当前搜索值
currentSearchRef.current = searchValue;
setLoading(true);
// 清除之前的定时器
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
// 设置新的定时器
timeoutRef.current = setTimeout(() => {
fetchData(searchValue || '', (result) => {
// 确保返回的数据对应的是当前搜索值
if (currentSearchRef.current === searchValue) {
setData(result);
setLoading(false);
}
});
}, debounceTime);
};
// 处理搜索
const handleSearch = (newValue) => {
// 如果允许空值搜索,或者有搜索值
if (loadOnEmpty || newValue) {
loadData(newValue);
} else {
// 如果不允许空值搜索且搜索值为空,则清空数据
setData([]);
}
};
// 处理值变化
const handleChange = (newValue) => {
setValue(newValue);
};
// 组件挂载时加载初始数据
useEffect(() => {
if (initialLoad) {
loadData('');
}
// 组件卸载时清除定时器
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);
return (
<Select
showSearch
value={value}
placeholder={placeholder}
style={style}
defaultActiveFirstOption={false}
suffixIcon={null}
filterOption={false}
onSearch={handleSearch}
onChange={handleChange}
notFoundContent={loading ? "搜索中..." : "无匹配数据"}
loading={loading}
options={[...defaultOptions, ...data]}
onFocus={() => {
// 当聚焦时,如果允许空值搜索且当前没有数据,则加载数据
if (loadOnEmpty && data.length === 0) {
loadData('');
}
}}
/>
);
};
// 定义默认属性值
SearchSelect.defaultProps = {
style: null,
placeholder: '请选择',
defaultOptions: [],
debounceTime: 500,
loadOnEmpty: true,
initialLoad: false
};
export default SearchSelect;
更多推荐


所有评论(0)