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

React按工作地点筛选JSON职位数据时URL参数不更新问题排查

问题背景

我正在为当前开发的项目构建筛选功能,需要解析后端API返回的JSON数据,根据工作地点字段筛选职位帖子并完成展示。

原问题代码
useEffect(async () => {
  let condition = await getJobs();
  switch (jobCondition) {
    case 'On-site': condition.filter((condition.jobLocation === 'in_person'));
      break;
    case 'Remote': condition.filter((condition.jobLocation === 'remote'));
      break;
    case 'Hybrid': condition.filter((condition.jobLocation === 'hybrid'));
      break;
    default:
      condition = null;
  }
  if (condition != null) {
    const params = new URLSearchParams({
      jobs: jobFilter || null,
      location: locationFilter || null,
      since: datePosted || null,
      conditions: condition.data,
    });
    history.push({ pathname: '/', search: `${params.toString()}` });
    return;
  }
  const params = new URLSearchParams({
    jobs: jobFilter || null,
    location: locationFilter || null,
    since: null,
    conditions: null,
  });
  history.push({ pathname: '/', search: `${params.toString()}` });
}, [jobCondition]);

上述代码运行存在明显异常,执行后URL参数完全没有发生变化,无法实现预期的筛选跳转效果。

问题原因

代码存在4个核心错误,直接导致逻辑中断、筛选失效:

  • useEffect不支持直接传入async函数作为回调。useEffect要求回调返回值为清理函数或undefined,async函数默认返回Promise对象,会导致React无法正确处理副作用执行时序,容易引发执行异常。
  • 对Array.filter()的用法完全错误:
    • filter方法接收的入参必须是判断函数,原代码传入的是一个布尔表达式(condition.jobLocation === 'xxx'),不是函数,调用时会直接抛出类型错误;
    • filter不会修改原数组,执行后会返回全新的筛选后数组,原代码没有接收filter的返回值,即使语法正确,筛选结果也不会被保存。
  • 数据结构理解错误:从后续代码condition.data可以判断,await getJobs()返回的是接口响应对象,职位列表存储在响应的data字段中,原代码直接在响应对象(非数组)上调用filter方法,会直接触发「filter不是一个函数」的报错,导致后续路由跳转逻辑完全终止,这也是URL参数完全没有变化的直接原因。
  • 默认分支逻辑错误:当没有匹配到筛选条件时,原代码直接将condition置为null,会导致无筛选条件时参数构造逻辑不符合预期。
修复方案

修复后的代码如下:

useEffect(() => {
  // 不要直接给useEffect传async回调,在内部定义异步函数执行
  const fetchAndFilterJobs = async () => {
    const res = await getJobs();
    // 先从响应中取出职位数组
    const jobList = res.data;
    let filteredJobs = jobList;

    switch (jobCondition) {
      case 'On-site':
        // 传入正确的筛选回调,接收返回的新数组
        filteredJobs = jobList.filter(item => item.jobLocation === 'in_person');
        break;
      case 'Remote':
        filteredJobs = jobList.filter(item => item.jobLocation === 'remote');
        break;
      case 'Hybrid':
        filteredJobs = jobList.filter(item => item.jobLocation === 'hybrid');
        break;
      default:
        // 默认不做筛选,保留全量列表
        filteredJobs = jobList;
    }

    const params = new URLSearchParams({
      jobs: jobFilter || null,
      location: locationFilter || null,
      since: jobCondition ? datePosted || null : null,
      conditions: jobCondition ? JSON.stringify(filteredJobs) : null
    });
    history.push({ pathname: '/', search: params.toString() });
  };

  fetchAndFilterJobs();
}, [jobCondition, jobFilter, locationFilter, datePosted, history]);

注意:URLSearchParams不支持直接传入对象/数组作为参数值,如果需要把筛选后的职位列表放到URL参数中,需要先序列化为字符串格式,否则会被自动转成[object Object]导致参数失效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:46:03