如何使用React Query实现搜索API接口对接Typeahead搜索组件
搜索场景大学选择功能实现方案
原有代码问题说明
- React Query请求写死了搜索参数
name=middle,无法和用户输入联动 - 接口返回的是大学信息对象数组,未提取
Typeahead组件需要的学校名称字段 - 未做请求节流/防抖,输入过程中会产生大量无效请求
- 未处理加载、错误、空输入等边界状态
完整实现代码
首先确保引入依赖和基础样式:
import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import axios from 'axios'; import { Typeahead } from 'react-bootstrap-typeahead'; import { useDebounce } from 'use-debounce'; // 引入组件必需样式 import 'react-bootstrap-typeahead/css/Typeahead.css';
组件内核心逻辑:
// 存储选中的学校结果 const [selected, setSelected] = useState([]); // 存储用户实时输入的搜索关键词 const [searchKeyword, setSearchKeyword] = useState(''); // 对输入值做300ms防抖,避免频繁触发请求 const [debouncedKeyword] = useDebounce(searchKeyword, 300); // 动态拉取匹配的大学数据 const { isLoading, isError, data: universityOptions } = useQuery({ // queryKey绑定搜索关键词,关键词变化时自动重新请求 queryKey: ['university', debouncedKeyword], queryFn: async () => { // 空关键词直接返回空数组,不发起无效请求 if (!debouncedKeyword.trim()) return []; const { data } = await axios.get( 'http://universities.hipolabs.com/search', { params: { name: debouncedKeyword } } ); // 提取大学名称字段,作为下拉选项数据源 return data.map(item => item.name); }, // 仅当输入字符≥2个时才发起请求,减少无效接口调用 enabled: debouncedKeyword.trim().length >= 2, // 搜索结果缓存5分钟,相同关键词重复搜索无需重复请求 staleTime: 5 * 60 * 1000 });
搜索下拉组件配置:
<Typeahead id="university-search" onChange={setSelected} options={universityOptions || []} placeholder="输入学校名称搜索..." selected={selected} // 绑定输入事件,实时同步用户输入内容 onInputChange={setSearchKeyword} // 传递加载状态,组件会自动显示加载提示 isLoading={isLoading} // 自定义不同场景下的空提示文案 emptyLabel={ isError ? '搜索失败,请稍后重试' : debouncedKeyword.length < 2 ? '请输入至少2个字符开始搜索' : '未找到匹配的学校' } />
可选调整说明
- 若不想引入
use-debounce依赖,可自行实现简易防抖逻辑替换 - 如果需要下拉选项展示更多学校信息(比如所属国家),可以不用提取
name字段直接返回原始对象数组,给Typeahead加labelKey="name"属性指定显示字段即可 - 可根据业务需求调整防抖时长、触发搜索的最小字符长度、缓存时间等参数
内容的提问来源于stack exchange,提问作者Wajid Ali
相关产品推荐
相关产品推荐

