You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>
    </>
  );
};

解决方案

问题核心是城市下拉框未接收选中省份作为过滤条件,始终基于全量数据生成选项。按以下步骤修改即可解决:

  1. 给城市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; // 新增可选字段
    }
    
  2. 修改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);
      }
    
      ...
    };
    
  3. 优化省份选择后的城市默认值逻辑
    当选中省份后,若没有对应城市则清空城市选中值:

    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 10:04:55