React省份联动城市下拉框过滤功能异常问题排查
React省市级联下拉框过滤失效问题
我要实现的功能是:选择省份后,城市下拉框仅展示该省份下属的城市。但目前的问题是,选完省份后,城市下拉框只会自动定位到该省份的第一个城市,却依然显示所有省份的城市列表。
我尝试过对filteredData进行过滤和映射,然后将cityDropdownFilter状态设置为filteredCities[0],但这并没有解决城市列表未过滤的问题。
相关代码片段
Header.tsx中的省份选择处理函数
const handleDropdownFilterProvince = ( e: React.ChangeEvent<HTMLSelectElement> ) => { useFilterStore.setState({ provinceDropdownFilter: e.target.value }); // 根据选中的省份过滤数据 const filteredCitiesSet = new Set<string>( filteredData .filter((item) => item.state === e.target.value) .map((item) => item.city) ); const filteredCities = Array.from(filteredCitiesSet); useFilterStore.setState({ cityDropdownFilter: filteredCities[0] }); console.log("handle province dropdown cities", filteredCities); // 需要在这里实现清除不匹配省份的城市的逻辑 // ^^^ 还没搞清楚这里的逻辑 };
Header.tsx完整代码
export const Header = ({ data, isLoading, error }: HeaderProps) => { ... // 引入全局状态 const { manufacturerDropdownFilter, provinceDropdownFilter, cityDropdownFilter, priceRangeFilter, } = useFilterStore(); const filteredData = data.map((group) => group.equipments).flat(); ... const handleDropdownFilterProvince = ( e: React.ChangeEvent<HTMLSelectElement> ) => { useFilterStore.setState({ provinceDropdownFilter: e.target.value }); // 根据选中的省份过滤数据 const filteredCitiesSet = new Set<string>( filteredData .filter((item) => item.state === e.target.value) .map((item) => item.city) ); const filteredCities = Array.from(filteredCitiesSet); useFilterStore.setState({ cityDropdownFilter: filteredCities[0] }); console.log("handle province dropdown cities", filteredCities); // 需要在这里实现清除不匹配省份的城市的逻辑 // ^^^ 还没搞清楚这里的逻辑 }; const handleDropdownFilterCity = ( e: React.ChangeEvent<HTMLSelectElement> ) => { useFilterStore.setState({ cityDropdownFilter: e.target.value }); }; ... return ( <> ... <Dropdown data={filteredData} value={provinceDropdownFilter} onChange={handleDropdownFilterProvince} filterType="state" /> <Dropdown data={filteredData} value={cityDropdownFilter} onChange={handleDropdownFilterCity} filterType="city" /> ... </> ); };
Dropdown.tsx完整代码
export const Dropdown: React.FC<DropdownProps> = ({ data, onChange, value, filterType, }) => { ... // 根据filterType过滤数据 const filteredOptions = data.filter((i) => { if (filterType === "manufacturer") { return i.manufacturer; } if (filterType === "state") { return i.state; } if (filterType === "city") { return i.city; } return false; }); // 去重,避免重复显示相同选项(比如"TX"、"Los Angeles") const uniqueValues = new Set<string>(); for (let i = 0; i < filteredOptions.length; i++) { uniqueValues.add(filteredOptions[i][filterType] as string); } return ( <> <Select aria-label="Select" placeholder={getCustomPlaceholder(filterType) as string} value={value} onChange={handleFilters} > {Array.from(uniqueValues) .sort() .map((value) => ( <option key={value} value={value}> {value} </option> ))} </Select> </> ); };
解决方案
问题核心是城市下拉框未接收选中省份作为过滤条件,始终基于全量数据生成选项。按以下步骤修改即可解决:
给城市Dropdown传递选中省份参数
在Header组件的return部分,为城市Dropdown添加selectedProvince属性:<Dropdown data={filteredData} value={cityDropdownFilter} onChange={handleDropdownFilterCity} filterType="city" selectedProvince={provinceDropdownFilter} // 新增属性 />同时更新
DropdownProps类型定义:interface DropdownProps { data: YourDataType[]; // 替换为你的实际数据类型 onChange: (e: React.ChangeEvent<HTMLSelectElement>) => void; value: string; filterType: "manufacturer" | "state" | "city"; selectedProvince?: string; // 新增可选字段 }修改Dropdown组件的过滤逻辑
当filterType为city且存在选中省份时,先过滤出对应省份的数据,再生成城市选项:export const Dropdown: React.FC<DropdownProps> = ({ data, onChange, value, filterType, selectedProvince, }) => { ... // 先处理省份过滤(仅城市下拉框生效) let filteredOptions = [...data]; if (filterType === "city" && selectedProvince) { filteredOptions = filteredOptions.filter(item => item.state === selectedProvince); } // 再按原逻辑筛选对应字段存在的项 filteredOptions = filteredOptions.filter((i) => { if (filterType === "manufacturer") { return i.manufacturer; } if (filterType === "state") { return i.state; } if (filterType === "city") { return i.city; } return false; }); // 去重逻辑保持不变 const uniqueValues = new Set<string>(); for (let i = 0; i < filteredOptions.length; i++) { uniqueValues.add(filteredOptions[i][filterType] as string); } ... };优化省份选择后的城市默认值逻辑
当选中省份后,若没有对应城市则清空城市选中值:const handleDropdownFilterProvince = ( e: React.ChangeEvent<HTMLSelectElement> ) => { const selectedProvince = e.target.value; useFilterStore.setState({ provinceDropdownFilter: selectedProvince }); const filteredCitiesSet = new Set<string>( filteredData .filter((item) => item.state === selectedProvince) .map((item) => item.city) ); const filteredCities = Array.from(filteredCitiesSet); // 有城市则选第一个,无城市则清空 useFilterStore.setState({ cityDropdownFilter: filteredCities.length > 0 ? filteredCities[0] : "" }); };
修改完成后,城市下拉框会根据选中的省份动态过滤出对应城市,不再显示全量城市列表。
内容的提问来源于stack exchange,提问作者jrad09
相关产品推荐
相关产品推荐

