
今天我们来聊聊使用 React + hook + Antd 实现联动模糊搜索。
需要从用户选中的机构中,联动加载相对应的有权处理人。
由于有权处理人数据量较大,并且需要动态加载,无法将所有枚举都放在前端静态资源中。
需要根据所选择的机构,默认加载一部分的处理人,剩下的,根据用户手输的数据,与后台交互,模糊匹配对应的选项。
实现思路
主要代码实现
Debounceselect:动态加载的下拉框
import React, { forwardRef, useImperativeHandle, useState, uSEMemo } from 'React'; import { Select, Spin } from "antd"; import debounce from "lodash/debounce"; Export const DebounceSelect = forwardref(({ fetchoptions, debouncetimeout = 800, ...props}, ref) => { const [Fetching, setFetching] = useState(false); const [options, setOptions] = useState([]); const [userlistBackUp, setUserListBackUp] = useSate([]); const [centerHandleOrg, setCenterHandleOrg] = useState(""); const debounceFetcher = useMemo(() => { // keyWord:用户输入的关键字 const loadOptions = (keyWord) => { if(!keyWord) return setOptions([]); setFetching(true); // 同时触发父组件的fetchUserList,并传入参数 fetchOptions({centerHandleOrg, keyWord}).then(newOptions => { setOptions(newOptions); setFetching(false) }) } return debounce(loadOptions, debounceTimeout); },[ centerHandleOrg, fetchOptions, debounceTimeout]) // 向父组件抛出对象 useImperativeHandle(ref, () => ({ update: (list = [], _centerHandleOrg = "") => { setOptions(list); setUserListBackUp(list); setCenterHandleOrg(_centerHandleOrg); } })); return( <Select allowClear showSearch filterOption={false} onSearch={debounceFetcher} onClear={() => setOptions(userListBackUp)} notFoundContent={fetching ? <Spin size="small"/> : null} {...props} options={options} /> ) })
父组件中机构和处理人的部分静态代码实现
// ...相关依赖引入
<Row>
<Col span={11}>
<FORM.Item label="处理机构" name="centerHandleOrg">
<Select
allowClear
showSearch
filterOption={(val, option) => selectFilterIsBool(val, option)}
onSelect={this.centerHandleOrgChangeHandle}
onClear={() => this.debounceSelectRef.current.upDate()}>
{this.state.centerHandleOrgList.map(item => (
<Option key={item.orgcode} value={item.orgCode}>
{item.orgCode}-{item.orgName}
</Option>
))}
</Select>
</form.Item>
</Col>
<Col span={11}>
<Form.Item label="处理人" name="centerHandleUser">
<DebounceSelect
ref={this.debounceSelectRef}
placeholder="请输入进行查找"
fetchOption={this.fetchUserList}
/>
</Form.Item>
</Col>
</Row>部分使用到的方法代码实现如下
// 由于select是默认按照label,value做键的
const reNameObj = (list) =>
list.map(({userName, userCode, ...rest}) => ({
label: `${userCode}-${userName},`
value: userCode,
...rest,
}))
// 前端进行模糊匹配的时候,如果返显的下拉选项为拼接后的话,会被拆成一个数组,无法直接匹配
const selectFilterIsBool = (val = "", option = "") => {
if(option.PRops.children){
if(Objec.prototype.toString.call(option.props.children) !== "[Object Array]"){
return option.props.children.includes(val);
}
return option.props.children.join("").includes(val);
}
return false;
}部分效果预览
搜索中:

总结
使用防抖减少接口频繁调用
使用缓存减少性能消耗
使用数据备份这种方式提示用户体验。






网友评论文明上网理性发言 已有0人参与
发表评论: