反应输入去抖仍在执行方法

React input debounce still executing method

我正在尝试实施去抖动但无法使其正常工作(每次输入更改的请求仍然太多)。我正在使用 underscore 中的 debounce 方法。我为此示例简化了代码:

import { debounce } from "underscore";

const fetch = (value) => {
    axios.post("/uri", { search: value }).then(({ data }) => {   
      setBreeds(data);
    });
  };

<input
  type="text"
  onChange={e => debounce(fetch(e.target.value), 2000)}
  autoComplete="off"
/>

我这里哪里做错了?

你的根本问题是 debounce 需要一个函数作为它的第一个参数。您将 fetch(e.target.value) 作为第一个参数传递,它甚至不是一个函数(它是一个 Promise)。但是为了评估该参数是什么,每次 onChange 事件发生时都必须调用 fetch - 这就是为什么您看到它被调用得太频繁的原因。

“正确”的写法是:

onChange={debounce(e => fetch(e.target.value), 2000)}

然而,即使那样也不会按预期工作,仅仅是因为每次组件重新呈现时都必须重新计算 onChange 函数 - 所以尽管 debounce 内部将拒绝调用其底层函数,直到 2自上次以来已经过去了数秒,该函数将在重新渲染之间更改身份,即使就您而言它是“相同的函数”。仅仅因为两个函数具有相同的实现和效果并不意味着它们是相同的函数引用。

因此您需要提取函数 e => fetch(e.target.value) 以便它具有单一标识。这在函数组件中如何做并不是很明显(在 class 中很容易,只需将函数设为实例方法 - 我假设这是一个函数组件,尽管使用名为 [=17 的函数=]),但可以通过 useRefuseCallback 来完成 - 例如,请参阅 this 文章,以及 React 站点上这两个 Hook 的文档。

根据 https://underscorejs.org/#debounce , d​​ebounce() 需要有一个函数作为第一个参数,而(在我看来)你正在发送函数调用的结果。也许:

onChange={e => debounce(fetch(e.target.value), 2000)}

可以改为:

onChange={e => debounce(() => fetch(e.target.value), 2000)}

尝试创建一个 debounceCall 函数并使用 e.persist

 const debounceCall = debounce(e => {
    axios.post("/uri", { search: e.target.value }).then(({ data }) => {
       setBreeds(data);
    });
 }, 2000);

  <input
    type="text"
    name="inp"
    onChange={e => {
      e.persist();
      debounceCall(e);
    }}
    autoComplete="off"
  />