Comment utiliser les hooks anti-shake dans React
P粉497463473
P粉497463473 2024-01-28 22:15:30
0
2
428

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;
}


J'avais l'habitude de fabriquer et d'utiliser useDebouncedes crochets. Cependant, l'utilisation de useDebounce dans les événements de redimensionnement pose quelques problèmes. useDebounce hook Doit être exécuté par-dessus le composant car il utilise useEffect en interne. Cependant, la fonction de redimensionnement est configurée pour s'exécuter sur useEffect comme indiqué ci-dessous.

De plus, le code ci-dessus prend la valeur comme facteur, mais je pense que nous devons la recevoir comme rappel pour utiliser le code ci-dessous.

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

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

Comment utiliser le code ci-dessus pour exploiter le useDebounce existant ?

P粉497463473
P粉497463473

répondre à tous(2)
P粉098417223

Si vous utilisez la fonction anti-rebond directement dans votre composant React, cela ne fonctionnera pas car une nouvelle fonction sera créée à chaque rendu, à la place vous pouvez utiliser ce useDebouncehook :

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 Assurez-vous qu'à chaque rendu, la référence à la fonction est mise à jour.

Pour plus d'informations à ce sujet, consultez la Réaction du mode "Dernière référence"

P粉894008490

Je pense qu'au lieu d'implémenter l'anti-rebond via useEffect, il est préférable d'implémenter la logique anti-rebond en tant que fonction.

useEffectdeps 引用的状态改变时执行。也就是说,由于是一个如果只按照执行流程就容易漏掉的逻辑,所以后期维护时很难弄清楚这个useEffect Exécuté lorsque l'état référencé par deps change. En d'autres termes, comme il s'agit d'une logique facile à manquer si vous suivez uniquement le processus d'exécution, il est difficile de déterminer de quel processus ce

est dérivé lors d'une maintenance ultérieure, et il est également difficile de déboguer.

Exemple

自定义反跳

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());


lodashSi vous utilisez , vous pouvez simplement importer pour l'utiliser.

Lodash Debounce

import { debounce } from 'lodash';
const debounceOnChange = debounce(() => {
  console.log("This is a debounce function");
}, 500);
J'espère que cela aide :)🎜
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal