React TypeScript级联选择组件搜索后选项加载异常求助
搜索后级联Select组件仅显示单个值,无法生成完整选项列表的问题修复
问题分析
非搜索模式下,父级Select选择后能正确生成子级的去重选项列表,级联逻辑正常;但触发搜索功能后,仅展示搜索结果中的单个对应值,后续Select组件没有生成完整的可用选项列表。核心原因是搜索分支的逻辑只做了数据过滤,没有为后续级联Select生成并更新对应的选项数据源。
修复方案
- 搜索完成后,基于过滤后的数据集,为每个后续级联Select生成去重选项并更新对应状态
- 清理Select组件中冗余的状态监听逻辑,避免重复触发更新导致的状态混乱
- 在Select组件中对选项列表做去重处理,避免重复渲染MenuItem
修改后的代码
Select组件
// Select component import React, { useEffect, useId, useState } from "react" import _ from "lodash" import { FormControl, Select, InputLabel, MenuItem, SelectChangeEvent } from "@mui/material" import ISelect from "@/types/select" const SelectComponent: React.FC<ISelect> = (props) => { const { val, label, keyVal, dataList, onChangeVal } = props const [data, setData] = useState<any[]>([]) const [value, setVal] = useState<any>(val || "") const id = useId() // 监听外部传入值更新本地选中状态 useEffect(() => { if (val !== undefined) { setVal(val) } }, [val]) // 根据数据源和字段生成去重的选项列表 useEffect(() => { if (keyVal && dataList && dataList.length > 0) { const mappedData = _.map(dataList, keyVal) const uniqueData = _.uniq(mappedData) setData(uniqueData) } else { setData([]) } }, [keyVal, dataList]) // 选项只有一个时自动选中 useEffect(() => { if (keyVal && data.length === 1 && onChangeVal) { const autoSelectVal = data[0] setVal(autoSelectVal) onChangeVal(keyVal, autoSelectVal) } }, [data, keyVal, onChangeVal]) const handleChange = (e: SelectChangeEvent) => { const _val = e.target.value setVal(_val) onChangeVal?.(keyVal, _val) } return ( <FormControl color="info" sx={{ minWidth: 100, fontSize: 13 }} size="small" fullWidth> <InputLabel>{label}</InputLabel> <Select onChange={handleChange} value={value} disabled={data.length === 0} label={label} > {data.map((d, i) => ( <MenuItem key={`${keyVal}_${id}_${i}`} value={d}> {d} </MenuItem> ))} </Select> </FormControl> ) } export default SelectComponent
过滤器与值处理函数
const onChangeVal = (type: string, val: any) => { const _filterData = _(sensitivity) const currentData = data || {} let _filters = {} let _unique: null | string = null let setItem: any switch (type) { case "year": _unique = "Type" setItem = setType _filters = isSearch ? { ...currentData } : { year: val } break case "Type": _unique = "Groupings" setItem = setGrouping _filters = isSearch ? { ...currentData } : { year: currentData.year, Type: val } break case "Groupings": _unique = "Region" setItem = setRegion _filters = isSearch ? { ...currentData } : { year: currentData.year, Type: currentData.Type, Groupings: val } break case "Region": _unique = "Type5" setItem = setType5 _filters = isSearch ? { ...currentData } : { year: currentData.year, Type: currentData.Type, Groupings: currentData.Groupings, Region: val } break case "Type5": _unique = "Type4" setItem = setType4 _filters = isSearch ? { ...currentData } : { year: currentData.year, Type: currentData.Type, Groupings: currentData.Groupings, Region: currentData.Region, Type5: val } break case "Type4": _unique = "Type3" setItem = setType3 _filters = isSearch ? { ...currentData } : { year: currentData.year, Type: currentData.Type, Groupings: currentData.Groupings, Region: currentData.Region, Type5: currentData.Type5, Type4: val } break case "Type3": _unique = "Type2" setItem = setType2 _filters = isSearch ? { ...currentData } : { year: currentData.year, Type: currentData.Type, Groupings: currentData.Groupings, Region: currentData.Region, Type5: currentData.Type5, Type4: currentData.Type4, Type3: val } break case "Type2": _filters = isSearch ? { ...currentData } : { year: currentData.year, Type: currentData.Type, Groupings: currentData.Groupings, Region: currentData.Region, Type5: currentData.Type5, Type4: currentData.Type4, Type3: currentData.Type3, Type2: val } setIsSearch(false) break case "Search": resetData() _filters = { ...val } setIsSearch(true) const filteredData = _filterData.filter(_filters).value() // 为后续所有级联Select生成去重选项并更新状态 setType(_.uniqBy(filteredData, "Type")) setGrouping(_.uniqBy(filteredData, "Groupings")) setRegion(_.uniqBy(filteredData, "Region")) setType5(_.uniqBy(filteredData, "Type5")) setType4(_.uniqBy(filteredData, "Type4")) setType3(_.uniqBy(filteredData, "Type3")) setType2(_.uniqBy(filteredData, "Type2")) // 如果过滤后有数据,自动填充第一个结果到表单 if (filteredData.length > 0) { setData({ year: filteredData[0].year, Type: filteredData[0].Type, Groupings: filteredData[0].Groupings, Region: filteredData[0].Region, Type5: filteredData[0].Type5, Type4: filteredData[0].Type4, Type3: filteredData[0].Type3, Type2: filteredData[0].Type2 }) } break } if (_unique && typeof setItem === "function") { const _groupData = _filterData.filter(_filters).uniqBy(_unique).value() setItem(_groupData) } if (type !== "Search") { setData({ ...currentData, ..._filters }) } }
内容的提问来源于stack exchange,提问作者anuj
相关产品推荐
相关产品推荐

