如何在 React 中实现一个防抖(debounce)的搜索输入框?
如何在 React 中实现一个防抖(debounce)的搜索输入框?
回答与解析:
在 React 中实现防抖搜索输入框,核心是使用防抖函数来限制搜索请求的频率,避免用户每输入一个字符就触发一次 API 请求。可以通过自定义 Hook 或直接在组件中使用 useCallback 和 useEffect 结合防抖逻辑实现。
示例代码如下:
import { useState, useEffect, useCallback } from 'react';
// 防抖函数
function debounce(func, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
function SearchInput() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
// 模拟搜索 API
const performSearch = async (searchTerm) => {
if (searchTerm.trim() === '') {
setResults([]);
return;
}
// 假设调用 API
const mockResults = [`Result for "${searchTerm}" 1`, `Result for "${searchTerm}" 2`];
setResults(mockResults);
};
// 使用 useCallback 缓存防抖函数,避免每次渲染都重新创建
const debouncedSearch = useCallback(
debounce((q) => performSearch(q), 500),
[]
);
useEffect(() => {
debouncedSearch(query);
// 清理函数可选(防抖本身已通过 clearTimeout 控制)
return () => {
// 可在此处清除最后一个 timeout(非必需)
};
}, [query, debouncedSearch]);
return (
<div>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
<ul>
{results.map((result, index) => (
<li key={index}>{result}</li>
))}
</ul>
</div>
);
}
export default SearchInput;
关键点解析:
- 防抖原理:通过
setTimeout延迟执行函数,若在延迟期间再次触发,则清除之前的定时器并重新计时。 - useCallback:防止
debouncedSearch在每次渲染时重新创建,否则useEffect会因依赖变化而频繁执行。 - 副作用管理:在
useEffect中调用防抖函数,确保query变化后触发搜索逻辑。 - 性能优化:避免高频输入导致大量无效请求,提升用户体验和服务器负载。
注意:若使用第三方库(如 lodash),可直接用 _.debounce,但需注意在组件卸载时取消 pending 的调用,防止内存泄漏。

发表评论 (审核通过后显示评论):