使用React中的防抖hooks的方法
P粉497463473
P粉497463473 2024-01-28 22:15:30
0
2
418

import { useEffect, useState } from 'react';

export default function useDebounce(text: string, delay: number) {
  const [value, setValue] = useState('');

  useEffect(() => {
    const timerId = setTimeout(() => {
      setValue(text);
    }, delay);
    return () => {
      clearTimeout(timerId);
    };
  }, [text, delay]);
  return value;
}


我曾经制作和使用 useDebounce 钩子。 但是,在调整大小事件中使用 useDebounce 存在一些问题。 useDebounce hook 必须在组件顶部运行,因为它在内部使用了 useEffect。 但是,调整大小函数设置为在 useEffect 上运行,如下所示。

此外,上面的代码将值作为一个因素,但我认为我们需要接收它作为回调才能使用下面的代码。

  useEffect(() => {
    const handler = () => {
      if (liRef.current) setWidth(liRef.current.clientWidth);
    };

    window.addEventListener('resize', handler);
    return () => window.removeEventListener('resize', handler);
  }, []);

如何使用上面的代码来利用现有的useDebounce?

P粉497463473
P粉497463473

全部回复(2)
P粉098417223

如果你直接在React组件中使用debounced函数,它将不起作用,因为每个渲染都会创建一个新函数,相反,你可以使用这个useDebounce钩子:

function useDebounce(callback, delay) {
  const callbackRef = React.useRef(callback)
  React.useLayoutEffect(() => {
    callbackRef.current = callback
  })
  return React.useMemo(
    () => debounce((...args) => callbackRef.current(...args), delay),
    [delay],
  )
}

useRef 确保它与上次提供的函数相同,并且 useLayoutEffect 确保在每次渲染时,对函数的引用都会更新。

有关这方面的更多信息,请参阅“最新参考”模式反应

P粉894008490

我认为与其通过useEffect实现去抖,不如将去抖逻辑实现为一个函数。

useEffectdeps 引用的状态改变时执行。也就是说,由于是一个如果只按照执行流程就容易漏掉的逻辑,所以后期维护时很难弄清楚这个useEffect是从哪一个流程衍生出来的,调试起来也比较困难。

示例

自定义反跳

function debounce(func, timeout = 300) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      func.apply(this, args);
    }, timeout);
  };
}
function saveInput() {
  console.log('Saving data');
}
const processChange = debounce(() => saveInput());


如果您使用lodash,则只需导入即可使用它。

Lodash Debounce

import { debounce } from 'lodash';
const debounceOnChange = debounce(() => {
  console.log("This is a debounce function");
}, 500);

希望这有帮助:)

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板