如何在 React 中实现一个可复用的防抖(debounce)自定义 Hook?

如何在 React 中实现一个可复用的防抖(debounce)自定义 Hook?

回答:

可以使用 useRef 和 useEffect 创建一个防抖 Hook,例如:

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

function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value);
  const timerRef = useRef<NodeJS.Timeout | null>(null);

  useEffect(() => {
    // 清除上一个定时器
    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }

    // 设置新的定时器
    timerRef.current = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

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

  return debouncedValue;
}

使用示例:

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

  useEffect(() => {
    if (debouncedSearchTerm) {
      // 执行搜索逻辑,例如调用 API
      console.log('Searching for:', debouncedSearchTerm);
    }
  }, [debouncedSearchTerm]);

  return <input value={inputValue} onChange={e => setInputValue(e.target.value)} />;
}

解析:

  • 防抖(Debounce)是一种限制函数调用频率的技术,常用于输入框搜索、窗口 resize 等高频事件。
  • useDebounce Hook 接收一个值和延迟时间,返回一个“延迟更新”的值。
  • 使用 useRef 保存定时器引用,避免在每次渲染时丢失。
  • useEffect 监听原始值变化:每次值变化时清除旧定时器,设置新定时器。
  • 清理函数确保组件卸载时不会因定时器导致内存泄漏或状态更新错误。
  • 此 Hook 是通用的,可用于任何需要防抖的场景,提升性能并减少不必要的副作用执行。

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

昵称:
邮箱:
内容: