React多条件筛选功能问题:无法基于已筛选结果进行二次筛选
React多条件筛选功能问题:无法基于已筛选结果进行二次筛选
看起来你遇到的核心问题是每次筛选都从原始的全量jobs数据重新过滤,而不是基于上一次筛选后的结果——这是因为你当前的逻辑里,不管是城市筛选还是经验筛选,都是直接拿jobs(原始API数据)来做过滤,然后直接覆盖filteredJobs,所以第二个筛选会完全忽略第一个的筛选结果。
我给你调整下思路:不要直接修改filteredJobs,而是把筛选条件(选中的城市、选中的经验)单独存成状态,然后每次基于原始的jobs数据,同时应用所有筛选条件来计算最终的filteredJobs。这样不管哪个条件变化,都会自动组合所有条件得到正确的结果。
具体修改步骤如下:
- 新增两个状态来保存当前的筛选条件,初始值都设为"All"
- 修改筛选函数,不再直接更新
filteredJobs,而是更新对应的筛选条件状态 - 用
useEffect监听筛选条件和原始jobs的变化,每次变化时重新计算符合所有条件的结果
修改后的完整代码如下:
import { useState, useEffect } from 'react'; import Header from './Header'; // 假设你的Header组件路径正确 import JobCard from './JobCard'; // 假设你的JobCard组件路径正确 const Home = () => { const [jobs, setJobs] = useState([]); // 初始设为空数组,避免undefined的问题 const [filteredJobs, setFilteredJobs] = useState([]); // 新增筛选条件状态 const [selectedCity, setSelectedCity] = useState("All"); const [selectedExp, setSelectedExp] = useState("All"); const jobData = async () => { try { const data = await fetch("http://localhost:3031/jobs"); const json = await data.json(); setJobs(json); } catch (err) { console.error("获取数据失败:", err); } }; useEffect(() => { jobData(); }, []); // 监听筛选条件和原始jobs的变化,重新计算筛选结果 useEffect(() => { if (!jobs.length) return; // 原始数据还没加载时不执行 let result = [...jobs]; // 应用城市筛选 if (selectedCity !== "All") { result = result.filter(val => val.location === selectedCity); } // 应用经验筛选 if (selectedExp !== "All") { result = result.filter(val => val.yoe === selectedExp); } setFilteredJobs(result); }, [jobs, selectedCity, selectedExp]); // 依赖项:原始数据和两个筛选条件 const cityFilter = (e) => { setSelectedCity(e.target.value); // 只更新筛选条件 }; const expFilter = (e) => { setSelectedExp(e.target.value); // 只更新筛选条件 }; return ( <div> <Header /> <div> <select name="select city" value={selectedCity} onChange={cityFilter}> <option value="All"> All</option> <option value="Bengaluru">Bengaluru</option> <option value="Pune">Pune</option> <option value="Hyderabad">Hyderabad</option> <option value="New Delhi">New Delhi</option> <option value="Gurugram">Gurugram</option> </select> </div> <div> <select name="select experience" value={selectedExp} onChange={expFilter}> <option value="All">All</option> <option value="Internship">Internship</option> <option value="Fresher">Fresher</option> <option value="Early Professional">Early Professional</option> <option value="Professional">Professional</option> </select> </div> <div style={{ display: "flex", flexWrap: "wrap", padding: "8px", gap: "4px", justifyContent: "center", marginTop: "8px", }} > {filteredJobs.map(({ id, title, img, location, role, yoe }) => ( <JobCard key={id} id={id} title={title} location={location} role={role} /> ))} </div> </div> ); }; export default Home;
几个关键的优化点:
- 把
jobs和filteredJobs的初始值设为空数组,避免了?.map里的可选链判断,同时也防止了数据未加载时的错误 - 新增的
selectedCity和selectedExp状态专门保存筛选条件,让筛选逻辑和结果计算分离,更清晰 - 用一个
useEffect来统一处理筛选逻辑,只要原始数据或筛选条件变化,就重新计算结果,这样不管先选城市还是先选经验,都会基于所有条件得到正确的过滤结果 - 给select加上了
value属性,让select的选中状态和React状态保持同步,符合受控组件的规范
这样调整后,你就能实现多条件叠加筛选的效果了——比如先选Bengaluru,再选Fresher,会显示班加罗尔的应届生岗位,而不是回到全量数据里找应届生岗位。
备注:内容来源于stack exchange,提问作者Harshdeep Singh
相关产品推荐
相关产品推荐

