如何在 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)}
    />
  );
}

关键点解析:

  1. 防抖函数 debounce:通过 setTimeout 延迟执行目标函数,每次新输入会清除上一次定时器,确保只有在用户停止输入一段时间(如 500ms)后才真正触发搜索。

  2. useCallback:用于缓存函数引用,防止在每次渲染时创建新的 debounce 实例,避免 useEffect 不必要地重复执行或定时器混乱。

  3. useEffect 监听 query:当用户输入变化(query 更新)时,触发防抖后的搜索函数。

  4. 注意清理定时器:上述 debounce 实现已在闭包中自动处理了 clearTimeout,但若组件卸载前仍有 pending 的定时器,可考虑在 useEffect 中返回 cleanup 函数进一步保障(在复杂场景下推荐)。

进阶建议:也可使用第三方库如 lodash.debounce,但需注意配合 useCallback 避免重复创建防抖函数。

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

昵称:
邮箱:
内容: