如何在 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 timerRef = useRef();

  useEffect(() => {
    // 清除上一次的定时器
    timerRef.current = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

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

  return debouncedValue;
}

使用示例:

function SearchInput() {
  const [inputValue, setInputValue] = useState('');
  const debouncedValue = useDebounce(inputValue, 500);

  useEffect(() => {
    // 只有当用户停止输入 500ms 后才发起搜索请求
    if (debouncedValue) {
      console.log('Searching for:', debouncedValue);
      // 调用 API 搜索
    }
  }, [debouncedValue]);

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

解析:
防抖(debounce)是一种常见的优化技术,用于限制高频操作(如搜索输入、窗口 resize)的执行频率。在 React 中,通过自定义 Hook 封装防抖逻辑可以提升代码复用性。关键点包括:

  1. 使用 useRef 存储定时器 ID,避免每次渲染都创建新的变量;
  2. 在 useEffect 中设置 setTimeout,并在依赖项(value 或 delay)变化时清除旧定时器;
  3. 利用清理函数(return)确保组件卸载时不会发生内存泄漏或状态更新错误;
  4. 返回延迟更新后的值,供外部组件使用。

这种方式既保持了逻辑内聚,又避免了在组件内部重复编写防抖代码。

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

昵称:
邮箱:
内容: