React JS中基于文本输入从API搜索并筛选匹配结果的求助
排查React搜索匹配问题的解决方案
咱们一步步来拆解你的问题:首先看了你提供的API数据结构,它是直接返回全部案件信息的静态数组,没有后端筛选接口,所以问题大概率出在前端的处理逻辑上——要么没做前端过滤,要么过滤逻辑有错误。
1. 核心问题梳理
你的需求是**同时匹配派出所(policestation)和案件编号(crime number)**后展示结果,核心要做的就是:
- 正确保存用户选择的筛选条件到组件状态
- 用条件过滤API返回的全部数据
- 渲染过滤后的匹配结果,而非原始全部数据
2. 具体实现步骤
第一步:初始化组件状态
在React组件中用useState保存关键数据:
import { useState, useEffect } from 'react'; function CaseSearch() { // 用户选择的派出所 const [selectedStation, setSelectedStation] = useState(''); // 用户输入的案件编号 const [selectedCrimeNum, setSelectedCrimeNum] = useState(''); // API返回的全部原始案件数据 const [allCases, setAllCases] = useState([]); // 过滤后的匹配结果 const [matchedCases, setMatchedCases] = useState([]);
第二步:拉取API数据
组件挂载时获取全部数据,并初始化结果列表:
useEffect(() => { fetch('https://api.myjson.com/bins/e69i9/') .then(res => res.json()) .then(data => { setAllCases(data); // 初始可显示全部数据,也可以设为空 setMatchedCases(data); }) .catch(err => console.error('数据拉取失败:', err)); }, []);
第三步:添加实时过滤逻辑
当用户修改筛选条件时,自动过滤数据:
useEffect(() => { // 还没拿到API数据时直接返回 if (!allCases.length) return; const filtered = allCases.filter(caseItem => { // 派出所匹配逻辑:选了才校验,否则默认符合 const isStationMatch = selectedStation ? caseItem.policestation === selectedStation : true; // 案件编号匹配逻辑:注意API字段带空格,必须用方括号访问! const isCrimeNumMatch = selectedCrimeNum ? caseItem['crime number'] === selectedCrimeNum : true; // 两个条件同时满足才保留 return isStationMatch && isCrimeNumMatch; }); setMatchedCases(filtered); }, [selectedStation, selectedCrimeNum, allCases]);
第四步:渲染筛选结果
把筛选控件和匹配结果渲染出来,重点是渲染matchedCases而非原始数据:
return ( <div className="search-container"> {/* 派出所选择下拉框 */} <select value={selectedStation} onChange={(e) => setSelectedStation(e.target.value)} > <option value="">请选择派出所</option> {/* 从原始数据提取唯一派出所选项,避免重复 */} {[...new Set(allCases.map(item => item.policestation))].map(station => ( <option key={station} value={station}>{station}</option> ))} </select> {/* 案件编号输入框 */} <input type="text" placeholder="输入案件编号" value={selectedCrimeNum} onChange={(e) => setSelectedCrimeNum(e.target.value)} /> {/* 渲染匹配结果 */} <div className="results"> {matchedCases.length === 0 ? ( <p>没有找到匹配的案件信息</p> ) : ( matchedCases.map(caseItem => ( <div key={caseItem['crime number']} className="case-card"> <h4>案件编号:{caseItem['crime number']}</h4> <p>所属派出所:{caseItem.policestation}</p> <p>案件类型:{caseItem.crimetype}</p> <p>日期:{caseItem.date}</p> </div> )) )} </div> </div> ); } export default CaseSearch;
3. 常见错误排查
你之前返回全部数据,大概率是以下原因之一:
- 字段名错误:比如把
policestation写成policeStation(大小写不符),或者忽略crime number的空格写成crimeNumber,导致过滤条件永远为true,返回全部数据。 - 逻辑符号错误:用了
||(或)而非&&(且),导致只要匹配一个条件就返回,不符合“同时匹配”的需求。 - 渲染原始数据:直接渲染了
allCases而非过滤后的matchedCases,所以筛选操作不会改变结果。
按照上面的步骤实现,就能达成“仅返回匹配结果”的需求了。
内容的提问来源于stack exchange,提问作者kasim521
相关产品推荐
相关产品推荐

