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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 13:12:59