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

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

回答:
可以在 React 中使用 useRefuseEffect 钩子配合 lodash.debounce 或手写防抖函数来实现防抖搜索输入框。以下是一个使用自定义防抖函数的示例:

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

function useDebounce(callback, delay) {
  const timeoutRef = useRef(null);

  useEffect(() => {
    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, []);

  return (...args) => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
    }
    timeoutRef.current = setTimeout(() => callback(...args), delay);
  };
}

export default function SearchInput() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);

  const debouncedSearch = useDebounce((searchTerm) => {
    // 模拟 API 调用
    fetch(`/api/search?q=${searchTerm}`)
      .then(res => res.json())
      .then(data => setResults(data));
  }, 500);

  const handleChange = (e) => {
    const value = e.target.value;
    setQuery(value);
    debouncedSearch(value);
  };

  return (
    <div>
      <input
        type="text"
        value={query}
        onChange={handleChange}
        placeholder="Search..."
      />
      <ul>
        {results.map((item, index) => (
          <li key={index}>{item.title}</li>
        ))}
      </ul>
    </div>
  );
}

解析:

  • 防抖的核心思想是:在用户停止输入一段时间(如 500ms)后再触发搜索请求,避免在每次输入时都发送请求,提升性能并减少服务器压力。
  • useDebounce 是一个自定义 Hook,它返回一个防抖后的函数。内部使用 useRef 保存定时器 ID,确保在组件卸载时清除定时器以防止内存泄漏。
  • 每次输入变化时,handleChange 更新状态并调用防抖函数;如果在 delay 时间内再次触发,则清除之前的定时器并重新计时。
  • 此方案不依赖第三方库,但若项目中已使用 Lodash,也可以直接使用 _.debounce 并配合 useCallbackuseEffect 进行清理。

注意:若使用 _.debounce,需在组件卸载时调用 debouncedFn.cancel() 以避免异步副作用。

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

昵称:
邮箱:
内容: