Heim  >  Fragen und Antworten  >  Hauptteil

So verwenden Sie Anti-Shake-Hooks in React

import { useEffect, useState } from 'react';

export default function useDebounce(text: string, delay: number) {
  const [value, setValue] = useState('');

  useEffect(() => {
    const timerId = setTimeout(() => {
      setValue(text);
    }, delay);
    return () => {
      clearTimeout(timerId);
    };
  }, [text, delay]);
  return value;
}


Früher habe ich useDebounce Haken hergestellt und verwendet. Es gibt jedoch einige Probleme bei der Verwendung von useDebounce in Größenänderungsereignissen. useDebounce hook Muss auf der Komponente ausgeführt werden, da sie useEffect intern verwendet. Die Größenänderungsfunktion ist jedoch so eingerichtet, dass sie auf useEffect ausgeführt wird, wie unten gezeigt.

Außerdem verwendet der obige Code den Wert als Faktor, aber ich denke, wir müssen ihn als Rückruf erhalten, um den folgenden Code verwenden zu können.

  useEffect(() => {
    const handler = () => {
      if (liRef.current) setWidth(liRef.current.clientWidth);
    };

    window.addEventListener('resize', handler);
    return () => window.removeEventListener('resize', handler);
  }, []);

Wie verwende ich den obigen Code, um das vorhandene useDebounce zu nutzen?

P粉497463473P粉497463473287 Tage vor412

Antworte allen(2)Ich werde antworten

  • P粉098417223

    P粉0984172232024-01-29 11:40:03

    如果你直接在React组件中使用debounced函数,它将不起作用,因为每个渲染都会创建一个新函数,相反,你可以使用这个useDebounce钩子:

    function useDebounce(callback, delay) {
      const callbackRef = React.useRef(callback)
      React.useLayoutEffect(() => {
        callbackRef.current = callback
      })
      return React.useMemo(
        () => debounce((...args) => callbackRef.current(...args), delay),
        [delay],
      )
    }
    

    useRef 确保它与上次提供的函数相同,并且 useLayoutEffect 确保在每次渲染时,对函数的引用都会更新。

    有关这方面的更多信息,请参阅“最新参考”模式反应

    Antwort
    0
  • P粉894008490

    P粉8940084902024-01-29 09:59:42

    我认为与其通过useEffect实现去抖,不如将去抖逻辑实现为一个函数。

    useEffectdeps 引用的状态改变时执行。也就是说,由于是一个如果只按照执行流程就容易漏掉的逻辑,所以后期维护时很难弄清楚这个useEffect是从哪一个流程衍生出来的,调试起来也比较困难。

    示例

    自定义反跳

    function debounce(func, timeout = 300) {
      let timer;
      return (...args) => {
        clearTimeout(timer);
        timer = setTimeout(() => {
          func.apply(this, args);
        }, timeout);
      };
    }
    
    function saveInput() {
      console.log('Saving data');
    }
    const processChange = debounce(() => saveInput());
    
    
    

    如果您使用lodash,则只需导入即可使用它。

    Lodash Debounce

    import { debounce } from 'lodash';
    
    const debounceOnChange = debounce(() => {
      console.log("This is a debounce function");
    }, 500);
    

    希望这有帮助:)

    Antwort
    0
  • StornierenAntwort