您好,欢迎来到微智科技网。
搜索
您的当前位置:首页React中实现防抖功能的两种方式

React中实现防抖功能的两种方式

来源:微智科技网

问题

这有一个简单的防抖函数,短时间内多次触发同一事件,只执行最后一次

function debounce (fn, wait) {
  let timer = null
  return function (...args) {
    if (timer !== null) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      fn(args)
      timer = null
    }, wait)
  }
}

但问题是这个函数在react中使用不生效

export default () => {
  const handleClick = debounce(() => console.log("click fast!"), 1000));
  return (
     <button onClick={handleClick}>click fast!</button>
  );
};

原因就是函数式组件每次渲染,函数都会被重建,导致平时用的 debounce 函数中的timer会重新创建,进而导致防抖失效。

方案一

使用useRef来缓存timer变量

export default function () {
  const click = useDebounce((e: Event) => {
    console.log(e);
  }, 1000)
  
  return (
    <button onClick={click}>按钮</button>
  );
}

function useDebounce(fn: Function, delay: number) {
  const refTimer = useRef<number>();

  return function f(...args: any) {
    if (refTimer.current) {
      clearTimeout(refTimer.current);
    }
    refTimer.current = setTimeout(() => {
      fn(args);
    }, delay);
  }
}

方案二

使用useCallback来缓存函数,只要第二个参数传空数组,那么在组件重新选然时,useCallback中的函数就不会重新创建

export default function DeBounce() {
  const click = useCallback(clickInner(), []);

  function clickInner() {
    let timer: number;
    return function (e: Event) {
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(() => {
        console.log(e);
      }, 1000);
    }
  }

  return (
    <button onClick={click}>按钮</button>
  );
}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 7swz.com 版权所有 赣ICP备2024042798号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务