如何阻止React Query在搜索词长度≤2时发送搜索请求?
解决方案
核心思路是利用Tanstack React Query的enabled配置项,精准控制请求触发时机,同时修正组件内的条件渲染逻辑,完全符合React Hook规则。
1. 修改useSearch自定义Hook
在useQuery配置中添加enabled字段,仅当防抖后的搜索词长度大于2时才允许发起请求,从根源避免空字符串或短字符触发的无效请求:
import { useQuery } from "@tanstack/react-query"; import axios from "axios"; const fetchCitiesList = async (searchTerm: string) => { // 双重保险:防止意外传入不符合要求的搜索词 if (searchTerm.length <= 2) { return []; } const options = { method: "GET", url: "https://weatherapi-com.p.rapidapi.com/search.json", params: { q: searchTerm }, headers: { "X-RapidAPI-Key": import.meta.env.VITE_WEATHER_API_KEY, "X-RapidAPI-Host": import.meta.env.VITE_WEATHER_API_HOST, }, }; const { data } = await axios.request(options); return data as City[]; }; const useSearch = (searchTerm: string) => { return useQuery({ queryKey: ["search-city", searchTerm], queryFn: () => fetchCitiesList(searchTerm), // 关键配置:仅当搜索词长度>2时才执行查询 enabled: searchTerm.length > 2, // 初始值设为空数组,避免后续渲染时data为undefined initialData: [], }); }; export default useSearch;
2. 修复SearchBox组件的条件渲染问题
原组件中的if语句没有返回值,导致加载/错误提示无法正常显示,改为条件渲染写法:
import { TextInput } from "@mantine/core"; import { useDebouncedState } from "@mantine/hooks"; import useSearch from "../hooks/useSearch"; const SearchBox = () => { const [searchTerm, setSearchTerm] = useDebouncedState("", 400); const { data: suggestedCities, isError, isLoading } = useSearch(searchTerm); return ( <div> <TextInput defaultValue={searchTerm} onChange={(event) => setSearchTerm(event.currentTarget.value)} /> {/* 条件渲染加载状态 */} {isLoading && <h1>Loading...</h1>} {/* 条件渲染错误状态 */} {isError && <h1>Failed to fetch cities list!</h1>} {/* 可选:渲染搜索结果列表 */} {suggestedCities.length > 0 && ( <ul> {suggestedCities.map(city => ( <li key={city.id}>{city.name}</li> ))} </ul> )} </div> ); };
关键说明
enabled是React Query的内置配置,用于控制查询是否自动执行,完全符合Hook规则,无需在Hook外做条件判断。- 设置
initialData: []可以让data始终有值,避免渲染列表时出现undefined报错。 fetchCitiesList中的兜底判断是额外保险,防止极端情况下的无效请求。
内容的提问来源于stack exchange,提问作者frshaad
相关产品推荐
相关产品推荐

