useEffect过滤JSON更新URL参数时职位筛选不生效问题排查
核心问题成因
代码里一共5处逻辑错误,直接导致筛选失效:
- filter返回值未接收,过滤逻辑完全无效:
Array.filter()是不可变方法,不会修改原数组,只会返回过滤后的新数组。你在switch块里调用condition.filter(...)后没有把结果重新赋值给condition变量,过滤结果直接被丢弃,condition始终保持接口返回的原始值。同时你仅更新了URL参数,始终没有把过滤后的职位数据赋值给列表渲染对应的state变量,页面数据源没有更新,自然不会展示筛选后的结果。 - 错误await同步方法+无效空值判断:
Array.filter()是同步执行的,前面加await没有任何实际作用;同时JS中空数组[]是truthy值,你写的if (!filteredJobs) { return {} }永远不会触发——哪怕过滤结果是空数组,![]的计算结果为false,判断逻辑完全失效。 - 初始state值不匹配映射表:初始state值设为
On-site/Remote,不在你定义的conditionOptions映射键列表中,首次执行逻辑时conditionOptions[filterCondition]为undefined,第一次过滤直接返回空数组。 - Autocomplete组件属性传值错误:你解构state时把更新函数命名为
setJobConditionFilter,但给组件传options属性时直接传了jobConditionFilter——这个变量是state更新函数,不是预设的选项数组,导致下拉选项渲染异常,选中值出现字符串拼接错乱,就是你看到URL里conditions=remote/hybrid的异常值。 - URLSearchParams错误序列化null值:你给URLSearchParams传
null作为参数值时,值会被自动序列化成字符串"null",不是真正的空参数。后端接口拿到字段值是字符串"null",和“不传该参数”的预期逻辑不符,自然查询返回空数组。
修正后可运行代码
// 单独定义工作模式选项常量,避免传参错误 const JOB_CONDITION_OPTIONS = ['On-site', 'Remote', 'Hybrid']; // 相关state定义:空值代表不筛选该维度 const [jobCondition, setJobConditionFilter] = useState(''); // 补充职位列表渲染用的state(原代码缺失该部分,导致页面不更新) const [jobList, setJobList] = useState([]); // 数据请求方法:只负责拉取全量职位数据,移除冗余过滤逻辑 const getJobsLocation = useCallback(async () => { const jobs = await getJobs(); return jobs.data.nodes; }, []); useEffect(() => { getJobsLocation().then((allJobs) => { let filteredJobs = allJobs; // 过滤结果必须重新赋值给变量,同时统一字段判断逻辑 switch (jobCondition) { case 'On-site': filteredJobs = allJobs.filter((job) => job.jobFilter === 'in_person'); break; case 'Remote': filteredJobs = allJobs.filter((job) => job.jobFilter === 'remote'); break; case 'Hybrid': filteredJobs = allJobs.filter((job) => job.jobFilter === 'hybrid'); break; default: filteredJobs = allJobs; } // 组装URL参数:空值不写入参数,避免序列化为"null"字符串 const params = new URLSearchParams(); if (jobFilter) params.set('jobs', jobFilter); if (locationFilter) params.set('location', locationFilter); if (datePosted) params.set('since', datePosted); if (jobCondition) params.set('conditions', jobCondition); // 更新URL history.push({ pathname: '/', search: params.toString() }); // 更新列表state,驱动页面重渲染 setJobList(filteredJobs); }); // 依赖项补全所有用到的外部变量,避免闭包拿到旧值 }, [jobCondition, getJobsLocation, jobFilter, locationFilter, datePosted]); // JSX部分:options传入正确的选项常量 <CustomAutocomplete sx={{ width: '300px', marginLeft: '5px', marginTop: '10px', }} placeholder="Location" value={jobCondition} setValue={setJobConditionFilter} options={JOB_CONDITION_OPTIONS} endAdornmentIcon={( <div style={{ marginRight: '15px', marginTop: '-10px' }}> <ArrowDropDownIcon fontSize="10px" /> </div> )} />
内容的提问来源于stack exchange,提问作者Yuradzi
相关产品推荐
相关产品推荐

