React 防抖 Hook: useDebounce 实现原理详解

本文将详细解析 React 防抖 Hook (useDebounce) 的实现原理,并提供代码注释,帮助你理解防抖机制以及在 React 开发中如何使用 useDebounce Hook。

代码实现:

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

function useDebounce(fn, delay) {
  let { current } = useRef({ fn, timer: null });

  useEffect(() => {
    current.fn = fn;
  }, [current, fn]);

  return useCallback(function f(...args) {
    if (current.timer) {
      clearTimeout(current.timer);
    }

    current.timer = setTimeout(() => {
      current.fn.call(this, ...args);
    }, delay);
  }, [current, delay]);
}

export default useDebounce;

代码解释:

  1. import { useEffect, useCallback, useRef } from 'react';

    • 引入 React Hooks,useEffect 用于处理副作用,useCallback 用于记忆回调函数,useRef 用于创建可变引用。
  2. function useDebounce(fn, delay) {

    • 定义自定义 Hook useDebounce,接收两个参数:
      • fn: 要执行的函数
      • delay: 延迟时间
  3. let { current } = useRef({ fn, timer: null });

    • 使用 useRef 创建一个对象,包含两个属性:

      • fn: 保存传入的函数
      • timer: 保存定时器 ID,初始值为 null
    • 使用解构赋值将 current 属性从对象中提取出来。

  4. useEffect(() => { current.fn = fn; }, [current, fn]);

    • 使用 useEffect 监听 fncurrent 的变化。
    • fn 发生变化时,将新的 fn 赋值给 current.fn
    • 依赖项 [current, fn] 保证在 fncurrent 改变时才会执行 useEffect
  5. return useCallback(function f(...args) { ... }, [current, delay]);

    • 返回一个回调函数 f,使用 useCallback 包裹,避免在每次渲染时创建新的回调函数。
  6. if (current.timer) { clearTimeout(current.timer); }

    • 如果当前计时器已存在,则清除计时器,防止重复执行。
  7. current.timer = setTimeout(() => { current.fn.call(this, ...args); }, delay);

    • 设置一个新的计时器,延迟时间为 delay
    • 当计时器结束时,执行 current.fn 函数,并将参数 args 传递给它。
    • 使用 call 方法确保 current.fn 在正确的 this 上下文中执行。
  8. [current, delay]

    • 将回调函数 fcurrentdelay 作为依赖项,以确保每次渲染时返回的都是同一个回调函数,而不是新的引用。
  9. export default useDebounce;

    • 导出自定义 Hook useDebounce

总结:

useDebounce Hook 实现防抖机制,它接收要执行的函数和延迟时间作为参数。当函数被调用时,它会先清除之前的计时器,然后设置一个新的计时器。当计时器结束时,才会执行传入的函数。这样就实现了防抖功能,防止函数在短时间内被多次调用。

使用方法:

import useDebounce from './useDebounce';

function MyComponent() {
  const debouncedInputChange = useDebounce(handleInputChange, 500); // 延迟 500 毫秒

  // ...

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

在上述示例中,每次用户输入时都会调用 debouncedInputChange,而 debouncedInputChange 是一个防抖函数,它会延迟 500 毫秒才执行 handleInputChange 函数。这样就避免了在用户快速输入时频繁地触发 handleInputChange 函数,提升了用户体验。

React 防抖 Hook: useDebounce 实现原理详解

原文地址: https://www.cveoy.top/t/topic/oeMD 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录