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

React中如何实现文本框+双下拉选择的数组多条件过滤

多条件联合筛选职位列表实现方案

核心逻辑是三个筛选条件做与逻辑匹配,只有同时满足所有已设置筛选条件的职位才会渲染,同时修正react-select受控属性的写法问题,步骤如下:

  • 引入useMemo缓存过滤结果,避免无关重渲染导致的性能浪费
  • 注意react-select选中后返回的是完整选项对象(包含value和label字段),筛选时要取value属性和职位数据对应字段比对
  • 每个筛选条件做非空判断:如果用户没选对应下拉/没输入搜索词,就跳过该条件的校验
  • 把Select组件的defaultValue属性替换为value,符合React受控组件的写法,保证状态和视图同步

修正后的完整代码

import { useState, useMemo } from "react";
import Select from "react-select";

// 保留原有类型定义即可
const Positions = ({ positions }: DataProps) => {
  const locations = [
    { value: "canada", label: "Canada" },
    { value: "italy", label: "Italy" },
    { value: "france", label: "France" },
  ];

  const jobs = [
    { value: "uidesigner", label: "UI Designer" },
    { value: "back-end", label: "Backend Developer" },
    { value: "frontend", label: "Frontend Developer" },
  ];

  const [selectLocation, setSelectLocation] = useState(null);
  const [selectJobType, setSelectJobType] = useState(null);
  const [searchTerm, setSearchTerm] = useState("");

  // 缓存过滤后的职位列表
  const filteredPositions = useMemo(() => {
    if (!positions) return [];
    return positions.filter((position) => {
      // 搜索词匹配:默认不区分大小写匹配职位名称,需要匹配其他字段直接追加||判断即可
      const matchSearch = searchTerm.trim()
        ? position.position.toLowerCase().includes(searchTerm.trim().toLowerCase())
        : true;

      // 地点匹配:未选择地点时默认通过校验
      const matchLocation = selectLocation
        ? position.location === selectLocation.value
        : true;

      // 岗位类型匹配:未选择类型时默认通过校验
      const matchJobType = selectJobType
        ? position.type === selectJobType.value
        : true;

      // 三个条件同时满足才保留该职位
      return matchSearch && matchLocation && matchJobType;
    });
  }, [positions, searchTerm, selectLocation, selectJobType]);

  return (
    <div>
      <input
        type="search"
        placeholder="Search"
        onChange={(e) => setSearchTerm(e.target.value)}
      />

      <Select
        value={selectLocation}
        onChange={setSelectLocation}
        options={locations}
        instanceId="1"
        placeholder="Location"
        isClearable
      />

      <Select
        value={selectJobType}
        onChange={setSelectJobType}
        options={jobs}
        placeholder="Job Type"
        instanceId="2"
        isClearable
      />

      {filteredPositions.map((position) => (
        <SinglePosition
          category={position.category}
          type={position.type}
          location={position.location}
          position={position.position}
          key={position._id}
        />
      ))}
    </div>
  );
};

补充说明

  • 如果需要搜索词匹配更多字段(比如职位分类、工作地点),直接修改matchSearch的判断逻辑即可,比如追加|| position.location.toLowerCase().includes(searchTerm.trim().toLowerCase())就能同时搜索地点
  • 给Select加了isClearable属性,用户可以直接点叉清空已选筛选项,交互更友好,不需要可以直接删掉
  • 下拉选择的初始状态从空字符串改成了null,适配react-select的空值判断逻辑,避免初始值类型不匹配的问题

内容的提问来源于stack exchange,提问作者Elena Barden

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:15:40