React JS:去抖动

React JS: Debounce

考虑下面的 React 代码。在这里,我试图在输入发生变化时添加去抖动功能。它按预期工作,即当有 3000 毫秒的延迟时,也会发生 API 调用。但问题是, 假设我输入了 4 个字符,然后在 3000 毫秒后,发生了 4 个不同的 API 调用,而不是 1 个。 为什么会这样,我在做什么有什么问题吗?当我删除下面提到的行时,问题就解决了。这是为什么?

const [inputValue, setInputValue] = useState("");

const getSearch = (val) => {

    axios.get("url")
         .then(({ data }) => {      
         }).catch( () => {
         })
}    

const holdSearch = (callback, delay) => {
    let clear;
    return function(...args) {
       clearTimeout(clear);
       clear = setTimeout(() => {
                   callback(args[0]);
               }, delay);
    }
 }

const makeSearch = holdSearch(getSearch, 3000);

const handleChange = ({target}) => {
       
   setInputValue(target.value); // If I remove this statement, everything works as required
   makeSearch(target.value);

}

HTML 标签

<input value = {inputValue} onChange = {handleChange} />

每次组件呈现时,您都会创建一个新的 makeSearch 函数。这并没有什么不好,只是这也意味着您拥有一个全新的 clear 变量。所以调用 clearTimeout(clear) 永远不会做任何事情,因为 clear 总是一个全新的变量,其值为 undefined

您需要值从一个渲染到另一个渲染,这意味着使用 useRef:

const timerId = useRef();
const holdSearch = (callback, delay) => {
  return function (...args) {
    clearTimeout(timerId.current);
    timerId.current = setTimeout(() => {
      callback(args[0]);
    }, delay);
  }
}

When I remove the below-mentioned line, the issue solves. Why is that?

如果您不设置状态,则组件不会重新呈现,因此不会创建新变量。之后发生的任何 onChangeEvents 将转到相同的 handleChange 函数和相同的 makeSearch 函数。

但这不是您想要依赖的东西。你的组件应该这样写,如果它重新渲染它仍然可以工作,就像我上面的建议