如何在 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(() => {
    // 当 debouncedValue 变化时执行搜索
    if (debouncedValue) {
      console.log('发起搜索请求:', debouncedValue);
    }
  }, [debouncedValue]);

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

解析:

  • useDebounce 接收两个参数:需要防抖的值 value 和延迟时间 delay
  • 使用 useRef 保存定时器引用,避免在每次渲染时重新创建定时器导致无法正确清除。
  • useEffect 监听 valuedelay 的变化:每当 value 改变,先清除旧定时器,再设置新定时器;延迟时间结束后才更新防抖后的值。
  • 清理函数确保组件卸载或依赖项变化时不会出现内存泄漏或对已卸载组件的状态更新。
  • 此 Hook 适用于搜索输入、窗口 resize 监听、滚动事件等需要限制高频触发的场景。

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

昵称:
邮箱:
内容: