Des effets conflictuels?

Sep 22 2020

J'ai l'impression de rencontrer souvent ce problème.

Lors du chaînage de useEffects à déclencher après des changements d'état, je trouve que certains des useEffects de la chaîne ont des dépendances qui se chevauchent, ce qui les amène à se déclencher tous les deux plutôt que séquentiellement, après que l'un d'eux se soit mis à l'état.

Exemple: je déclenche une chaîne de useEffects lors des chapterIndexmises à jour.

let [ chapterIndex, setChapterIndex ] = useState<number | null>(0);

let [textTransitioning, setTextTransitioning] = useState<'out' | 'in' | null>(null);

useEffect(() => {
    setTextTransitioning('out')
}, [chapterIndex])

useEffect(() => {
    if (chapterIndex !== null) {
        const {
            current: chapter = null
        } = chapterRefs.current[chapterIndex];
            
        if (textTransitioning === 'in') {
            chapter?.classList.add('in');
        }
    }
}, [textTransitioning, chapterIndex])

Comment empêcher les deux de s'exécuter lors de chapterIndexmodifications? Je veux que le deuxième useEffect ne s'exécute qu'après que le premier useEffect soit défini sur textTransitioning. Lors de la suppression chapterIndexdu tableau de dépendances, j'obtiens l'erreur: 'React Hook useEffect a une dépendance manquante:' chapterIndex '. Incluez-le ou supprimez le tableau de dépendances. '

Réponses

Itaywazana Sep 22 2020 at 09:54

useEffectprend 2 arguments. Le premier est la fonction à appeler et le second est un tableau de variables appelé tableau de dépendances. le deuxième argument utilisé pour déclencher l'effet d'utilisation pendant qu'une des variables du tableau est en train de changer. donc si vous ne voulez useEffectpas être appelé lorsqu'une variable spécifique est modifiée, ne la passez pas dans le tableau des dépendances. votre code devrait être comme ça:

let [ chapterIndex, setChapterIndex ] = useState<number | null>(0);

let [textTransitioning, setTextTransitioning] = useState<'out' | 'in' | null>(null);

useEffect(() => {
      setTextTransitioning('out')
}, [chapterIndex])

useEffect(() => {
 if (chapterIndex !== null) {
     const {
         current: chapter = null
     } = chapterRefs.current[chapterIndex];
         
     if (textTransitioning === 'in') {
         chapter?.classList.add('in');
     }
 }
}, [textTransitioning]

Je pense que ce n'est pas très efficace de faire en sorte que l'un useEffectdéclenche l'autre mais peut-être que je ne vois pas l'image dans son ensemble

YogeshChaturvedi Sep 22 2020 at 09:58

Vous devez supprimer "ChapterIndex" du tableau dans le second useEffect. Ainsi, lors de la première exécution de useEffect, il mettra à jour le "textTransitioning" qui provoquera le deuxième déclencheur useEffect.

Pour une exécution plus conditionnelle de useEffect, vous pouvez vous référer https://reactjs.org/docs/hooks-effect.html