如何向API传递数字搜索参数?代码问题排查与修正
修复数字筛选参数传递问题
核心问题
- 数字筛选的三个输入框共用同一个状态,无法区分精确匹配与范围搜索的参数
- API请求时
numberFilters参数拼接语法错误,无法生成符合要求的格式
1. 调整状态结构
在FilterSearch组件中拆分状态,分别存储精确匹配值、最小值和最大值:
// FilterSearch.tsx import SearchByFilter from "@/lib/SearchByFilter"; import { useState } from "react"; import { BooleanSearch } from "./BooleanSearch"; import { SellerSearch } from "./SellerSearch"; import { NumberSearch } from "./NumberSearch"; export const FilterSearch: React.FC = () => { const [boolResult, setBoolResult] = useState<boolean>(false); const [sellerResult, setSellerResult] = useState<string>(""); // 拆分状态:精确匹配、最小值、最大值 const [exactCost, setExactCost] = useState<number | null>(null); const [minCost, setMinCost] = useState<number | null>(null); const [maxCost, setMaxCost] = useState<number | null>(null); const [dataResults, setDataResults] = useState<AllData[] | null>(null); async function handleSubmit() { try { const results = await SearchByFilter( boolResult, sellerResult, exactCost, minCost, maxCost ); setDataResults(results); } catch (error) { console.log(error); } } return ( <div> <BooleanSearch boolResult={boolResult} setBoolResult={setBoolResult} dataResults={dataResults} /> <hr /> <SellerSearch sellerResult={sellerResult} setSellerResult={setSellerResult} dataResults={dataResults} /> <hr /> <NumberSearch exactCost={exactCost} setExactCost={setExactCost} minCost={minCost} setMinCost={setMinCost} maxCost={maxCost} setMaxCost={setMaxCost} dataResults={dataResults} /> <button onClick={handleSubmit}>Filter</button> {dataResults && ( <ul> {dataResults.map((data) => ( <div key={data._id}> <h3>{data.title}</h3> <li>{data.seller}</li> <li>{data.cost}</li> </div> ))} </ul> )} </div> ); };
2. 更新NumberSearch组件
修改组件Props,让每个输入框绑定独立的状态更新逻辑:
// NumberSearch.tsx interface NumberSearchProps { exactCost: number | null; setExactCost: React.Dispatch<React.SetStateAction<number | null>>; minCost: number | null; setMinCost: React.Dispatch<React.SetStateAction<number | null>>; maxCost: number | null; setMaxCost: React.Dispatch<React.SetStateAction<number | null>>; dataResults: AllData[] | null; } export const NumberSearch = ({ exactCost, setExactCost, minCost, setMinCost, maxCost, setMaxCost, }: NumberSearchProps) => { return ( <div> <p>精确搜索成本</p> <input type="number" name="exactCost" onChange={(e) => setExactCost(e.target.value ? Number(e.target.value) : null)} value={exactCost !== null ? exactCost : ""} placeholder="输入精确值" /> <p>或输入范围</p> <input type="number" name="minCost" onChange={(e) => setMinCost(e.target.value ? Number(e.target.value) : null)} value={minCost !== null ? minCost : ""} placeholder="最小值" /> <input type="number" name="maxCost" onChange={(e) => setMaxCost(e.target.value ? Number(e.target.value) : null)} value={maxCost !== null ? maxCost : ""} placeholder="最大值" /> </div> ); };
3. 修复API请求参数拼接逻辑
修改SearchByFilter函数,根据传入的参数生成符合API要求的numberFilters格式:
// SearchByFilter.ts import axios, { AxiosError } from "axios"; export default async function SearchByFilter( boolResult?: boolean, sellerResult?: string, exactCost?: number | null, minCost?: number | null, maxCost?: number | null ): Promise<AllData[]> { const url = "https://search-practice-backend.vercel.app/api/v1/search"; const params: { [key: string]: string | boolean } = { promote: boolResult ?? false, seller: sellerResult ?? "", }; const filterParts: string[] = []; // 处理精确匹配 if (exactCost !== null && exactCost !== undefined) { filterParts.push(`cost=${exactCost}`); } // 处理最小值 if (minCost !== null && minCost !== undefined) { filterParts.push(`cost>=${minCost}`); } // 处理最大值 if (maxCost !== null && maxCost !== undefined) { filterParts.push(`cost<${maxCost}`); } // 拼接筛选条件 if (filterParts.length > 0) { params.numberFilters = filterParts.join(","); } try { const { data } = await axios.get(url, { params }); return data.final as AllData[]; } catch (error: unknown) { if (error instanceof AxiosError) { console.log(error.response); } throw error; } }
4. 保持数据接口不变
interface AllData { _id: string; title: string; cost: number; seller: string; }
修复后效果
- 单个输入框输入数字:生成
cost=xxx精确匹配参数 - 仅输入最小值:生成
cost>=xxx参数 - 仅输入最大值:生成
cost<xxx参数 - 同时输入min和max:生成
cost>=xxx,cost<xxx范围搜索参数
内容的提问来源于stack exchange,提问作者coderx
相关产品推荐
相关产品推荐

