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
相关产品推荐
相关产品推荐

