Maison > Questions et réponses > le corps du texte
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])
où 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粉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]); }
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]); }
useCustomEffect( () => { console.log("run custom effect", JSON.stringify(arr)); }, [arr], (a, b) => arrayEqual(a[0], b[0]) );
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)])