recherche

Maison  >  Questions et réponses  >  le corps du texte

将Inclure un tableau en tant que dépendance dans useEffect

Des données proviennent du long sondage toutes les 5 secondes et je souhaite que mon composant envoie une opération chaque fois qu'un élément du tableau (ou la longueur du tableau lui-même) change. Comment puis-je empêcher useEffect d'entrer dans une boucle infinie lors du passage d'un tableau en tant que dépendance, tout en parvenant à planifier certaines opérations si des valeurs changent ?

useEffect(() => {
  console.log(outcomes)
}, [outcomes])

outcomes 是一个 ID 数组,例如 [123, 234, 3212]。数组中的项目可能会被替换或删除,因此数组的总长度可能(但不一定)保持不变,因此传递 outcomes.length en tant que dépendance n'est pas le cas.

outcomes Sélecteur personnalisé de resélection :

const getOutcomes = createSelector(
  someData,
  data => data.map(({ outcomeId }) => outcomeId)
)


P粉748218846P粉748218846466 Il y a quelques jours618

répondre à tous(2)je répondrai

  • P粉464208937

    P粉4642089372023-10-18 15:49:11

    L'utilisation de JSON.stringify() ou de toute méthode de comparaison approfondie peut être moins efficace, si vous connaissez la forme de l'objet à l'avance, vous pouvez écrire votre propre hook d'effet pour déclencher un rappel à votre fonction d'égalité personnalisée en fonction du résultat.

    useEffect 的工作原理是检查依赖项数组中的每个值是否与前一渲染中的值相同,如果其中一个不是,则执行回调。因此,我们只需要使用 useRef 保留我们感兴趣的数据实例,并且仅在自定义相等性检查返回 false Attribuez une nouvelle instance pour déclencher l'effet.

    function arrayEqual(a1: any[], a2: any[]) {
      if (a1.length !== a2.length) return false;
      for (let i = 0; i < a1.length; i++) {
        if (a1[i] !== a2[i]) {
          return false;
        }
      }
      return true;
    }
    
    type MaybeCleanUpFn = void | (() => void);
    
    function useNumberArrayEffect(cb: () => MaybeCleanUpFn, deps: number[]) {
      const ref = useRef(deps);
    
      if (!arrayEqual(deps, ref.current)) {
        ref.current = deps;
      }
    
      useEffect(cb, [ref.current]);
    }
    

    Utilisation

    function Child({ arr }: { arr: number[] }) {
      useNumberArrayEffect(() => {
        console.log("run effect", JSON.stringify(arr));
      }, arr);
    
      return 
    {JSON.stringify(arr)}
    ; }

    Pour aller plus loin, nous pouvons également réutiliser ce hook en créant un hook d'effets qui accepte une fonction d'égalité personnalisée.

    type MaybeCleanUpFn = void | (() => void);
    type EqualityFn = (a: DependencyList, b: DependencyList) => boolean;
    
    function useCustomEffect(
      cb: () => MaybeCleanUpFn,
      deps: DependencyList,
      equal?: EqualityFn
    ) {
      const ref = useRef(deps);
    
      if (!equal || !equal(deps, ref.current)) {
        ref.current = deps;
      }
    
      useEffect(cb, [ref.current]);
    }
    

    Utilisation

    useCustomEffect(
      () => {
        console.log("run custom effect", JSON.stringify(arr));
      },
      [arr],
      (a, b) => arrayEqual(a[0], b[0])
    );
    

    Démonstration en direct

    répondre
    0
  • P粉662802882

    P粉6628028822023-10-18 12:32:21

    Vous pouvez passer JSON.stringify(outcomes) comme liste de dépendances :

    En savoir plus ici

    useEffect(() => {
      console.log(outcomes)
    }, [JSON.stringify(outcomes)])

    répondre
    0
  • Annulerrépondre