如何在 React 中实现一个防抖(debounce)的搜索输入框?

如何在 React 中实现一个防抖(debounce)的搜索输入框?

回答与解析:

在 React 中实现防抖搜索输入框,通常是为了避免用户在输入过程中频繁触发搜索请求(例如调用 API)。防抖的原理是:在用户停止输入一段时间(如 300ms)后再执行搜索逻辑。

实现方式如下(使用函数组件和 useState + useEffect):

import { useState, useEffect, useRef } from 'react';

function DebouncedSearchInput() {
  const [inputValue, setInputValue] = useState('');
  const [searchResult, setSearchResult] = useState(null);
  const debounceRef = useRef(null);

  useEffect(() => {
    // 清除上一次的定时器
    if (debounceRef.current) {
      clearTimeout(debounceRef.current);
    }

    // 如果输入为空,可选择跳过搜索
    if (inputValue.trim() === '') {
      setSearchResult(null);
      return;
    }

    // 设置新的防抖定时器
    debounceRef.current = setTimeout(() => {
      // 模拟 API 调用
      performSearch(inputValue).then(setSearchResult);
    }, 300);

    // 清理函数:组件卸载或 inputValue 变化时清除定时器
    return () => {
      if (debounceRef.current) {
        clearTimeout(debounceRef.current);
      }
    };
  }, [inputValue]);

  const performSearch = async (query) => {
    // 实际项目中替换为真实 API 调用
    return `搜索结果: "${query}"`;
  };

  return (
    <div>
      <input
        type="text"
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
        placeholder="输入搜索关键词..."
      />
      {searchResult && <div>{searchResult}</div>}
    </div>
  );
}

关键点解析:

  1. 使用 useRef 保存定时器引用,避免在每次渲染时丢失定时器 ID。
  2. useEffect 监听 inputValue 变化,每次变化都会清除旧定时器并设置新定时器。
  3. 在组件卸载或依赖变化时通过 return 清理定时器,防止内存泄漏或异步副作用。
  4. 防抖时间(如 300ms)可根据实际 UX 需求调整。

另外,也可以封装成自定义 Hook(如 useDebounce)以复用逻辑。这种方法结构更清晰,适合多处使用防抖的场景。

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

昵称:
邮箱:
内容: