基础部分请参考antd官网教程,该需求基于官网例子修改
antd官网
考虑到官网tags例子只支持label,所有在增加数字id与手输string这个问题上,需要在onchange事件里来处理,最终提交服务端的数据以及反显在选择框上展示的数据和下拉框选项的展示
import React, { useState } from 'react';
import { Select } from 'antd';
import { useDispatch, useSelector } from 'dva';
import _ from 'lodash';
const { Option } = Select;
export default FilterSelect = ({ onChange }) => {
const dispatch = useDispatch();
const selectResult = useSelector(state => state.antd).result;
const [withIdList, setWithIdList] = useState([]);
const [renderList, setRenderList] = useState([]);
const [value, setValue] = useState([]);
const handleSearch = value => {
dispatch({
type: 'antd/getSelectResult',
payload: {
value,
},
});
};
const handleChange = e => {
// 判断是增加,还是减少,分两种情况单独处理
let isAdd = e.length - renderList.length > 0;
let result = [...e];
let latestItem = result[result.length - 1];
if (isAdd) {
// 利用key上绑定数字ID来获取id值
if (!NaN(latestItem.key)) {
let filterResult = withIdList.filter(item => item.value == latestItem.key);
if (filterResult.length == 0) {
setWithIdList(val => [
...val,
{
value: latestItem.key,
label: latestItem.label,
},
]);
result[result.length - 1] = {
value: latestItem.label,
label: latestItem.label,
};
} else {
let findexIndex = withIdList.findIndex(item => item.value == latestItem.key);
let newArr = _.cloneDeep(withIdList);
newArr.splice(findexIndex, 0);
setWithIdList(newArr);
result.shift();
}
} else {
let filterResult = withIdList.filter(item => item.label == latestItem.label);
if (filterResult.length == 0) {
result[result.length - 1] = {
value: latestItem.label,
label: latestItem.label,
};
} else {
result.shift();
}
}
} else {
result = renderList.filter(item => e.some(ele => ele.value === item.value));
let newArr = withIdList.filter(item => e.some(ele => ele.value == item.label));
setWithIdList(newArr);
}
setRenderList(result);
setValue(result);
onChange(result);
};
return (
<Select
value={value}
mode="tags"
onSearch={_.debounce(() => {
handleSearch();
}, 400)}
onChange={handleChange}
filterOption={false}
optionLabelProp="label"
optionFilterProp="label"
labelInValue
>
{selectResult.map(item => (
<Option key={item.value} value={item.label} label={item.label}>
{item.label}
</Option>
))}
</Select>
);
};