如何使用ReactQuery实现支持多次查询触发的搜索页面?
React Query 实现搜索页面的查询逻辑
针对你需要的搜索页面查询流程,用React Query的useQuery就能搞定,核心是通过启用条件控制初始查询时机,并将搜索条件作为查询键依赖实现条件更新后的自动重查,具体实现如下:
核心思路
- 用
enabled选项控制查询是否执行,确保页面加载时无搜索条件不发起请求 - 将搜索条件作为
queryKey的一部分,条件变化时React Query会自动识别为新查询并重新执行 - 用React状态管理搜索输入值,输入变化时触发查询更新
代码实现示例
import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; // 模拟搜索接口请求,实际项目替换为你的后端API调用 const fetchSearchResults = async ({ queryKey }) => { const [_, searchTerm] = queryKey; const response = await fetch(`/api/search?term=${encodeURIComponent(searchTerm)}`); if (!response.ok) { throw new Error('搜索请求失败'); } return response.json(); }; function SearchPage() { // 维护搜索输入的状态 const [searchTerm, setSearchTerm] = useState(''); const { data: searchResults, isLoading, error } = useQuery({ // 把搜索条件加入查询键,确保条件变化时触发新查询 queryKey: ['search', searchTerm], queryFn: fetchSearchResults, // 仅当搜索条件不为空时执行查询 enabled: searchTerm.trim().length > 0, // 可选:设置缓存过期时间,相同搜索词短时间内重复查询会用缓存 staleTime: 5000, }); return ( <div className="search-page"> <input type="text" value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} placeholder="输入关键词搜索..." /> {/* 加载状态提示 */} {isLoading && <p>正在搜索...</p>} {/* 错误状态提示 */} {error && <p className="error">搜索出错:{error.message}</p>} {/* 搜索结果展示 */} {searchResults && searchResults.length > 0 ? ( <ul className="results-list"> {searchResults.map(item => ( <li key={item.id}>{item.content}</li> ))} </ul> ) : ( searchTerm.trim() && <p>未找到匹配结果</p> )} </div> ); } export default SearchPage;
关键细节说明
- queryKey的作用:React Query通过
queryKey区分不同的查询,当searchTerm变化时,queryKey改变,会自动触发新的查询,同时会缓存不同搜索词的结果,用户来回切换搜索词时能快速读取缓存(如果未过期)。 - enabled选项:这是控制初始查询时机的关键,页面加载时
searchTerm为空,enabled为false,不会发起无效请求;当用户输入有效内容后,enabled变为true,自动执行第一次搜索。 - 可选优化:防抖处理:如果用户输入频繁,可以给搜索词加防抖,减少不必要的请求,示例如下:
import { useDebounce } from '@tanstack/react-query'; // 在组件内替换为防抖后的搜索词 const debouncedSearchTerm = useDebounce(searchTerm, 300); // 后续queryKey和enabled都使用debouncedSearchTerm const { data: searchResults, isLoading, error } = useQuery({ queryKey: ['search', debouncedSearchTerm], queryFn: fetchSearchResults, enabled: debouncedSearchTerm.trim().length > 0, // ...其他配置 });
内容的提问来源于stack exchange,提问作者textual
相关产品推荐
相关产品推荐

