如何在 React 中使用 debounce hooks

pvp*_*p11 3 debouncing reactjs

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;
}


Run Code Online (Sandbox Code Playgroud)

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

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

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

    window.addEventListener('resize', handler);
    return () => window.removeEventListener('resize', handler);
  }, []);
Run Code Online (Sandbox Code Playgroud)

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

jya*_*gca 6

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

UseEffect当引用的状态发生变化时执行deps。换句话说,由于这是一个如果只按照执行流程就可能会被遗漏的逻辑,因此在useEffect后期维护时很难弄清楚它是从哪个流程衍生出来的,并且调试起来也很困难。

例子

Custom Debounce

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

<input type="text" onkeyup="processChange()" />
Run Code Online (Sandbox Code Playgroud)

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

Lodash Debounce

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

希望这可以帮助 :)