使用 React Hook 去抖或节流

Debounce or throttle with react hook

当来自输入字段的搜索查询参数更改时,我需要发出 api 请求,但前提是该字段不为空。

我正在测试在此站点上找到的几个答案,但无法使它们正常工作

第一个 this 带有自定义挂钩的

export function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => clearTimeout(handler);
  }, [value, delay]);

  return debouncedValue;
}

现在在我的组件中我这样做

const debouncedTest = useDebounce(() => {console.log("something")}, 1000);

但这似乎在每次重新渲染时都会被调用,而不管任何参数,我需要能够在 useEffect 中调用它,就像这样

useEffect(() => {
  if (query) {      
    useDebounce(() => {console.log("something")}, 1000);
  } else {
    //...
  }
}, [query]);

这当然行不通

另一种使用 lodash 的方法

const throttledTest = useRef(throttle(() => {
  console.log("test");   
}, 1000, {leading: false}))

但是我如何从上面的 useEffect 触发它?我不明白如何进行这项工作

谢谢

你的hook签名和你调用的时候不一样

也许你应该按照这些思路做一些事情:

const [state, setState] = useState(''); // name it whatever makes sense
const debouncedState = useDebounce(state, 1000);

useEffect(() => {
  if (debouncedState) functionCall(debouncedState);
}, [debouncedState])

我可以在这里快速指出一两件事。

useEffect(() => {
  if (query) {      
    useDebounce(() => {console.log("something")}, 1000);
  } else {
    //...
  }
}, [query]);

从技术上讲,您不能执行上述操作,useEffect 不能嵌套。

通常debounce与钩子无关。因为它是一个简单的函数。所以你应该首先寻找一个可靠的去抖动,创建一个或使用 lodash.debounce。然后构造您的代码以调用 debounce(fn)Fn 是您要延迟的原始函数。

另外 debounce 将处理经常变化的情况,这就是为什么你要应用去抖动来降低频率。因此,在 useEffect.

中很少见
  const debounced = debounce(fn, ...)
  const App = () => {
    const onClick = () => { debounced() }
    return <button onClick={onClick} />
  }

还有一个常见的问题,大家可能会在App里面使用debounce功能。这也不正确,因为 App 每次呈现时都会被触发。

稍后我可以提供一个相对更详细的解决方案。如果您也能解释一下您想做什么,将会有所帮助。