首页 > 解决方案 > 用反应钩子去抖动(几秒钟内只有一次触发功能)

问题描述

我需要在用户输入上实现标签搜索,但输入速度很快,我不想为用户输入的每个符号触发 DB 调用,所以我是古玩,有没有一种简单的好方法来消除 api 调用的抖动让我们说 - 一个3秒延迟后的时间?

现在我想出了这个:

  let searchDelay
  async function handleTagSearch(e) {
    clearTimeout(searchDelay)

    tagSearchPhraseSet(e.target.value)

    searchDelay = setTimeout(async () => {
      if (e.target.value.length > 3) {
        let res = await fetch('api/tag_seatch/' + e.target.value)
        res = await res.json() 

        console.log(res)
      }
    }, 3000)
  }

但这是正确的方法吗?

标签: reactjsreact-hooks

解决方案


你的解决方案看起来很有希望,如果你确保searchDelay数字在渲染之间保持不变,例如一个useRef钩子。

另一种解决方法是使用useEffect每次输入value更改时运行的钩子。从给定的函数中,useEffect您可以返回一个清除上次运行超时的函数。

例子

const { useState, useEffect } = React;

function App() {
  const [value, setValue] = useState("");
  const [result, setResult] = useState(null);

  useEffect(
    () => {
      if (value.length < 3) {
        setResult(null);
        return;
      }

      const timeout = setTimeout(() => {
        setResult(Math.random());
      }, 3000);

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

  return (
    <div>
      <input value={value} onChange={e => setValue(e.target.value)} />
      <div>{result}</div>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>


推荐阅读