如何在 React 中实现一个防抖(debounce)的搜索输入框?
如何在 React 中实现一个防抖(debounce)的搜索输入框?
回答与解析:
在 React 中实现防抖搜索输入框的核心思路是:延迟执行搜索请求,避免用户每输入一个字符就触发一次 API 调用,从而提升性能和用户体验。
实现方式如下(使用函数组件 + useCallback + useEffect + 自定义 debounce 函数):
import { useState, useCallback, useEffect } from 'react';
// 自定义防抖函数
function debounce(func, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => func.apply(this, args), delay);
};
}
export default function SearchInput() {
const [query, setQuery] = useState('');
// 模拟搜索函数
const performSearch = useCallback((searchTerm) => {
console.log('搜索:', searchTerm);
// 这里可以调用 API
}, []);
// 防抖后的搜索函数
const debouncedSearch = useCallback(
debounce((q) => performSearch(q), 500),
[performSearch]
);
useEffect(() => {
if (query.trim()) {
debouncedSearch(query);
}
}, [query, debouncedSearch]);
return (
<input
type="text"
placeholder="请输入搜索关键词"
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
);
}
关键点解析:
-
防抖函数 debounce:通过
setTimeout延迟执行目标函数,每次新输入会清除上一次定时器,确保只有在用户停止输入一段时间(如 500ms)后才真正触发搜索。 -
useCallback:用于缓存函数引用,防止在每次渲染时创建新的 debounce 实例,避免
useEffect不必要地重复执行或定时器混乱。 -
useEffect 监听 query:当用户输入变化(query 更新)时,触发防抖后的搜索函数。
-
注意清理定时器:上述 debounce 实现已在闭包中自动处理了 clearTimeout,但若组件卸载前仍有 pending 的定时器,可考虑在 useEffect 中返回 cleanup 函数进一步保障(在复杂场景下推荐)。
进阶建议:也可使用第三方库如 lodash.debounce,但需注意配合 useCallback 避免重复创建防抖函数。

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