如何在 React 中实现一个可复用的防抖(debounce)自定义 Hook?
如何在 React 中实现一个可复用的防抖(debounce)自定义 Hook?
回答:
可以使用 useRef 和 useEffect 创建一个 useDebounce 自定义 Hook,如下所示:
import { useState, useEffect, useRef } from 'react';
function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);
  const timeoutRef = useRef(null);
  useEffect(() => {
    // 清除上一个定时器
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
    }
    // 设置新的定时器
    timeoutRef.current = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);
    // 清理函数:组件卸载或依赖变化时清除定时器
    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, [value, delay]);
  return debouncedValue;
}
使用示例:
function SearchInput() {
  const [inputValue, setInputValue] = useState('');
  const debouncedValue = useDebounce(inputValue, 500);
  useEffect(() => {
    // 仅在防抖后的值变化时发起搜索请求
    if (debouncedValue) {
      fetchSearchResults(debouncedValue);
    }
  }, [debouncedValue]);
  return <input value={inputValue} onChange={e => setInputValue(e.target.value)} />;
}
解析:
- 防抖的目的是在用户连续输入时,延迟执行某些开销较大的操作(如搜索请求),避免频繁触发。
- 该 Hook 接收一个值和延迟时间,返回一个“防抖后”的值。
- 使用 useRef 存储定时器 ID,确保在多次 re-render 之间保持引用一致。
- useEffect 会在 value 或 delay 变化时重新设置定时器,并在组件卸载或依赖变化前清除旧定时器,防止内存泄漏和状态更新错误。
- 这种实现方式高度可复用,适用于任何需要防抖逻辑的场景(如搜索、表单验证、窗口 resize 监听等)。

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