Effetti contrastanti?

Sep 22 2020

Mi sento come se mi imbattessi spesso in questo problema.

Quando si concatenano useEffects da attivare dopo i cambiamenti di stato, trovo che alcuni degli useEffects nella catena hanno dipendenze sovrapposte che fanno sì che entrambi vengano attivati ​​piuttosto che in sequenza, dopo che uno è impostato su state.

Esempio: sto attivando una catena di useEffects durante gli chapterIndexaggiornamenti.

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])

Come posso impedire l'esecuzione di entrambi quando vengono chapterIndexmodificati? Voglio solo che il secondo useEffect venga eseguito dopo il primo useEffect impostato su textTransitioning. Quando rimuovochapterIndex dall'array delle dipendenze ricevo l'errore: 'React Hook useEffect ha una dipendenza mancante:' chapterIndex '. Includilo o rimuovi l'array delle dipendenze. '

Risposte

Itaywazana Sep 22 2020 at 09:54

useEffectaccetta 2 argomenti. la prima è la funzione da invocare e la seconda è un array di variabili chiamato array delle dipendenze. il secondo argomento utilizzato per attivare l'effetto use mentre una delle variabili dell'array sta cambiando. quindi se non vuoi useEffectessere chiamato quando viene modificata una variabile specifica, non passarla nell'array delle dipendenze. il tuo codice dovrebbe essere così:

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]

Penso che non sia molto efficiente fare in modo che uno useEffectinneschi l'altro ma forse non vedo l'intera immagine

YogeshChaturvedi Sep 22 2020 at 09:58

È necessario rimuovere "chapterIndex" dall'array nel secondo useEffect. Quindi, quando verrà eseguito il primo useEffect, verrà aggiornato il "textTransitioning" che causerà il secondo trigger useEffect.

Per un'esecuzione più condizionale di useEffect puoi fare riferimento https://reactjs.org/docs/hooks-effect.html