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

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

回答:
可以使用自定义 Hook 结合 lodash 的 debounce 函数,或手动使用 setTimeout/clearTimeout 实现防抖逻辑。

解析:
防抖的作用是限制高频事件(如 input 输入)触发的函数执行频率,只在用户停止输入一段时间后再执行。在 React 中常用场景是搜索框,避免每次输入都发起请求。

方法一:使用 lodash.debounce

import { useState, useCallback } from 'react';
import { debounce } from 'lodash';

const SearchInput = () => {
  const [query, setQuery] = useState('');

  const handleSearch = useCallback(
    debounce((value) => {
      console.log('发起搜索请求:', value);
      // 这里可以调用 API
    }, 500),
    []
  );

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

  return <input value={query} onChange={handleChange} placeholder="搜索..." />;
};

方法二:手动实现防抖(避免 lodash 依赖)

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

const useDebounce = (callback, delay) => {
  const timerRef = useRef();

  const debouncedCallback = useCallback((...args) => {
    clearTimeout(timerRef.current);
    timerRef.current = setTimeout(() => callback(...args), delay);
  }, [callback, delay]);

  // 可选:提供取消方法
  const cancel = useCallback(() => {
    clearTimeout(timerRef.current);
  }, []);

  return [debouncedCallback, cancel];
};

const SearchInput = () => {
  const [query, setQuery] = useState('');
  const [debouncedSearch, cancelSearch] = useDebounce((value) => {
    console.log('搜索:', value);
  }, 500);

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

  return <input value={query} onChange={handleChange} placeholder="搜索..." />;
};

注意事项:

  • 使用 useCallback 包裹防抖函数,避免每次渲染都创建新函数,导致 debounce 失效。
  • 在组件卸载时应清理定时器(如在 useEffect 中 return cancel),防止内存泄漏。
  • 如果使用 lodash.debounce,注意它返回的函数有 .cancel() 方法可用于清理。

该实现能有效减少不必要的 API 请求,提升性能和用户体验。

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

昵称:
邮箱:
内容: