简体   繁体   English

如何在 React.js 中实现去抖?

[英]How to implement debounce in React.js?

I am trying to implement debounce on search.我正在尝试对搜索实施debounce
The idea is to send a request to the api once user stopped typing.这个想法是在用户停止输入后向 api 发送请求。
I have a working example , which works fine.我有一个工作示例,效果很好。 You can see there that typed value will be printed on the screen once finished typing您可以在那里看到输入的值将在完成输入后打印在屏幕上
Now I am trying to implement the same feature on the same input with search functionality, but it doesn't work and throws an error:现在我试图在具有搜索功能的相同输入上实现相同的功能,但它不起作用并抛出错误:

TypeError: Cannot read properties of null (reading 'value')

Here is the component and the sandbox link这是组件和 沙箱链接

import React, { useState } from "react";
import data from "./MOCK_DATA.json";
function App() {
  const [name, setName] = useState("");
  const debounce = (func, delay) => {
    let timer;
    return (...arg) => {
      if (timer) clearTimeout(timer);
      timer = setTimeout(() => {
        func(...arg);
      }, delay);
    };
  };

  const onChangeHandler = (e) => {
    setName(e.target.value);
  };

  const debouncedOnChangeHandler = debounce(onChangeHandler, 1000);

  const filteredData = data.filter((el) =>
    el.first_name.toLowerCase().includes(name.toLowerCase())
  );
  return (
    <div>
      <div style={{ width: "100%" }}>Search</div>
      <input
        value={name}
        onChange={debouncedOnChangeHandler} //debouncedOnChangeHandler doesn't work because value is asynchronous
        //onChange={onChangeHandler} //this works fine without debounce function
        type="text"
        placeholder="search"
      />
      {filteredData &&
        filteredData.map((el) => <div key={el.id}>{el.first_name}</div>)}
    </div>
  );
}

export default App;

Any help will be appreciated.任何帮助将不胜感激。

There are some changes which you need to make,您需要进行一些更改,

First debouncedOnChangeHandler variable holds the function like,一个 debouncedOnChangeHandler 变量保存 function 之类的,

   const debouncedOnChangeHandler = (e) => {
    debounce(onChangeHandler(e), 1000);
   };

But whereas this doesn't pass the onChangeHandler as expected argument for debounce method.但是,这并没有将onChangeHandler作为debounce方法的预期参数传递。

So you need to just passdown the debounce function along with required parameters like,因此,您只需传递去抖动 function 以及所需的参数,例如,

const debouncedOnChangeHandler = debounce(onChangeHandler, 1000);

Second: You need to remove value={name} which is not needed in this context.第二:您需要删除在此上下文中不需要的value={name}

Forked Codesanbox:分叉的 Codesanbox:

编辑 mutable-mountain-ec3q9j

I suspect there's some re-rendering happening that stops your debounce function from being fully run.我怀疑发生了一些重新渲染会阻止您的 debounce function 完全运行。

Can you move the function out of the React component and see if that works?你能把 function 从 React 组件中移出,看看它是否有效吗?

As a side note both React and lodash have debounce functions that you can utilize, unless you're just looking to hone your skills here.附带说明一下,React 和 lodash 都有你可以使用的 debounce 函数,除非你只是想在这里磨练你的技能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM