useRef 与 debounce 函数的使用

Usage of useRef with debounce function

我在 React 组件中进行了以下设置,其中我使用了 throttle-debounce 包中的去抖功能来记录输入值以进行测试(实际上调用 API 来获取数据)。

import React, { useState, useRef } from 'react';
import debounce from 'throttle-debounce/debounce';

const MyComponent = () => {
  const [localSearchQuery, setLocalSearchQuery] = useState('');
  
  const setSearchQueryInParams = debounce(2000, value => console.log(value))

  const setSearchQuery = value => {
    setLocalSearchQuery(value);
    setSearchQueryInParams(value);
  };

  return (
    <>
      <Input
        value={localSearchQuery}
        onChange={setSearchQuery}
      />;
    </>
  );
};

但是,它没有按预期工作。如果我在输入框中键入 hello,我会在控制台中得到以下输出:

h
he
hel
hell
hello

但是,如果我用 useRef 包装去抖功能,它会按预期工作

const setSearchQueryInParams = useRef(debounce(2000, value => console.log(value))).current
Input: hello
Output in console: hello

我的问题是,为什么在没有 useRef 的情况下去抖动功能无法正常工作,以及 useRef 如何在这里发挥作用以获得所需的输出?

感谢您的帮助。

您需要使用 useCallback 和一个空的依赖项数组,而不是 useRef:

import React, { useState, useCallback } from 'react';
import debounce from 'throttle-debounce/debounce';

const MyComponent = () => {
  const [localSearchQuery, setLocalSearchQuery] = useState('');
  
  const setSearchQueryInParams = useCallback(debounce(2000, value => console.log(value)), []);

  const setSearchQuery = value => {
    setLocalSearchQuery(value);
    setSearchQueryInParams(value);
  };

  return (
    <>
      <Input
        value={localSearchQuery}
        onChange={setSearchQuery}
      />;
    </>
  );
};

原因是调用 debounce 总是 returns 一个新函数,因此您需要在重新渲染时存储该函数。

没有它,它就没有内部调用的 setTimeouts 的记忆,所以它不能使用它们来正确地去抖动。