优化前代码
import React, { useState, useEffect } from 'react';
import { Select, Checkbox, Divider } from 'antd';
interface Option {
label: string;
value: string | number;
}
interface SelectAllProps {
defaultValue: (string | number)[];
options: Option[];
width?: string;
onChange: (params: { selectData: (string | number)[] }) => void;
}
const SelectAll: React.FC<SelectAllProps> = (props) => {
const { defaultValue, options, width, onChange } = props;
const [status, setStatus] = useState<boolean>(false); // 全选状态
const [selectData, setSelectData] = useState<(string | number)[]>([]); // 当前选中值
useEffect(() => {
if (defaultValue.length) {
setSelectData(defaultValue);
setStatus(defaultValue.length === options.length); // 判断是否全选
}
}, [defaultValue, options]);
const handleSelectChange = (value: (string | number)[]) => {
setSelectData(value);
setStatus(value.length === options.length); // 更新全选状态
onChange({ selectData: value });
};
const handleSelectAll = (checked: boolean) => {
if (checked) {
const allValues = options.map((item) => item.value);
setSelectData(allValues);
setStatus(true);
onChange({ selectData: allValues });
} else {
setSelectData([]);
setStatus(false);
onChange({ selectData: [] });
}
};
return (
<Select
placeholder="请选择"
style={{ width: width || '300px' }}
mode="multiple"
maxTagCount="responsive"
allowClear
showSearch
value={selectData}
options={options}
filterOption={(input, option) =>
option?.label.toLowerCase().includes(input.toLowerCase()) ||
option?.value.toString().includes(input)
}
onChange={handleSelectChange}
dropdownRender={(menu) => (
<>
<div style={{ cursor: 'pointer' }}>
<Checkbox
checked={status}
onChange={(e) => handleSelectAll(e.target.checked)}
>
全选
</Checkbox>
</div>
<Divider style={{ margin: '0' }} />
{menu}
</>
)}
/>
);
};
export default SelectAll;
优化前,存在的问题
筛选后点击全选,选择的是所有列表,而不是过滤后的列表。
AI优化后
要优化过滤时的全选功能,使其仅选择过滤后的值,可以在 filterOption 和 onChange 的逻辑中动态更新全选的选项。以下是优化后的代码:
优化后的代码
import React, { useState, useEffect } from 'react';
import { Select, Checkbox, Divider } from 'antd';
interface SelectAllProps {
defauleValue: any[];
options: any[];
width?: string;
onChange: (params: any) => void;
}
const SelectAll: React.FC<SelectAllProps> = (props) => {
const { defauleValue, options, width, onChange } = props;
const [status, setStatus] = useState<boolean>(false); // 全选状态
const [selectData, setSelectData] = useState<any[]>([]); // 当前选中的值
const [filteredOptions, setFilteredOptions] = useState<any[]>(options); // 当前过滤后的选项
useEffect(() => {
if (defauleValue.length) {
setSelectData(defauleValue);
if (defauleValue.length === options.length) {
setStatus(true);
}
}
}, [defauleValue, options]);
const handleSelectChange = (value: any[], option: any[]) => {
setSelectData(value);
onChange({
selectData: value,
selectOption: option,
});
setStatus(value.length === filteredOptions.length); // 判断是否全选
};
const handleSelectAll = (checked: boolean) => {
if (checked) {
const allValues = filteredOptions.map((item) => item.value);
setSelectData(allValues);
setStatus(true);
onChange({
selectData: allValues,
selectOption: filteredOptions,
});
} else {
setSelectData([]);
setStatus(false);
onChange({
selectData: [],
selectOption: [],
});
}
};
const handleFilter = (input: string) => {
const filtered = options.filter(
(option) =>
option.label.toLowerCase().includes(input.toLowerCase()) ||
option.value.toString().includes(input)
);
setFilteredOptions(filtered); // 更新过滤后的选项
};
return (
<Select
placeholder="请选择"
style={{ width: width || '300px' }}
mode="multiple"
maxTagCount="responsive"
allowClear
showSearch
value={selectData}
options={filteredOptions}
filterOption={false} // 自定义过滤逻辑
onSearch={handleFilter} // 处理搜索
onChange={handleSelectChange}
dropdownRender={(menu) => (
<>
<div style={{ padding: '4px 8px 8px 12px', cursor: 'pointer' }}>
<Checkbox
checked={status}
onChange={(e) => handleSelectAll(e.target.checked)}
>
全选
</Checkbox>
</div>
<Divider style={{ margin: '0' }} />
{menu}
</>
)}
/>
);
};
export default SelectAll;
优化点说明
-
动态更新过滤后的选项:
- 使用
onSearch和setFilteredOptions动态更新当前过滤后的选项。
- 使用
-
全选仅选择过滤后的值:
- 在全选逻辑中,使用
filteredOptions而不是options,确保全选仅选择当前过滤后的值。
- 在全选逻辑中,使用
-
自定义过滤逻辑:
- 将
filterOption设置为false,并通过onSearch手动实现过滤逻辑。
- 将
-
全选状态更新:
- 根据
filteredOptions的长度和当前选中值的长度动态更新全选状态。
- 根据
效果
-
搜索过滤:
- 输入关键字时,选项会动态过滤。
-
全选功能:
- 全选仅选择当前过滤后的选项。
-
状态同步:
- 全选状态会根据当前过滤后的选项和选中值动态更新。
AI优化后,存在的问题
再次打开select全选组件,下拉选项没有重置为全部,导致已选择项显示异常。
人工再次优化后,AI分析
ASK Copilot: 分析在你的建议之后,我又优化了什么
在你的代码中,我注意到你已经实现了一些优化,以下是我对你的优化的分析和总结:
1. 使用 Set 去重
你在 onChange 的逻辑中使用了 Set 来对数组进行去重:
newData = Array.from(new Set([...seletData, ...a]));
- 优化点: 通过
Set去重,避免了重复值的出现,简化了去重逻辑。 - 改进效果: 代码更加简洁,性能更高,避免了手动遍历数组去重的复杂性。
2. 动态更新 filteredOptions
你在 onSearch 和 onDropdownVisibleChange 中动态更新了 filteredOptions:
onSearch={(value) => {
const filtered = options.filter((option) => {
return (
option.label.toLowerCase().includes(value.toLowerCase()) ||
option.value.toString().includes(value)
);
});
setFilteredOptions(filtered);
setStatus(
filtered.filter((item) => seletData.includes(item.value)).length ===
filtered.length
);
}}
- 优化点:
- 在搜索时动态过滤选项。
- 在下拉面板展开时重置
filteredOptions为原始的options。
- 改进效果:
- 搜索功能更加灵活,支持动态过滤。
- 在面板关闭后,选项列表能够恢复到初始状态。
3. 全选逻辑优化
你在 Checkbox 的 onChange 中实现了全选逻辑,并动态更新状态:
onChange={(e) => {
const a = filteredOptions.map((item) => item.value);
let newData: any[] = [];
if (e.target.checked) {
newData = Array.from(new Set([...seletData, ...a]));
} else {
newData = seletData.filter((item: any) => !a.includes(item));
}
const newOptions = options.filter((item) => newData.includes(item.value));
setSelectData(newData);
setSelectOption(newOptions);
setStatus(newData.length === options.length);
onChange({
seletData: newData,
selectOption: newOptions,
});
}}
- 优化点:
- 全选逻辑基于
filteredOptions,确保全选仅作用于当前过滤后的选项。 - 使用
Set去重,避免重复值。 - 动态更新
status,确保全选状态与选中值同步。
- 全选逻辑基于
- 改进效果:
- 全选功能更加智能,支持过滤后的全选。
- 状态同步更加准确,避免了逻辑错误。
4. 状态同步
你在多个地方动态更新了 status,确保全选状态与选中值保持一致:
setStatus(newData.length === options.length);
- 优化点:
- 在
onChange、onSearch和onDropdownVisibleChange中动态更新status。
- 在
- 改进效果:
- 全选状态能够实时反映当前选中值的状态,用户体验更好。
5. 代码结构清晰
你将逻辑分散到不同的事件处理函数中,例如 onSearch、onChange 和 onDropdownVisibleChange,使代码结构更加清晰。
- 优化点:
- 每个事件处理函数只负责一个功能,职责单一。
- 改进效果:
- 代码可读性更高,便于维护和扩展。
总结
你的优化主要体现在以下几个方面:
- 使用
Set去重: 简化了去重逻辑,提升了性能。 - 动态更新
filteredOptions: 支持搜索过滤,并在面板关闭时恢复初始状态。 - 全选逻辑优化: 全选功能更加智能,支持过滤后的全选。
- 状态同步: 确保全选状态与选中值保持一致。
- 代码结构清晰: 逻辑分工明确,代码更易读。