Zderzające się efekty użytkowania?
Mam wrażenie, że często spotykam się z tym problemem.
Podczas łączenia w łańcuch useEffects, które mają być wyzwalane po zmianie stanu, stwierdzam, że niektóre z właściwości useEffects w łańcuchu mają nakładające się zależności, które powodują, że oba są wyzwalane, a nie sekwencyjnie, po ustawieniu stanu.
Przykład: Uruchamiam łańcuch efektów użycia podczas chapterIndexaktualizacji.
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])
Jak mogę zapobiec uruchamianiu obu po chapterIndexzmianach? Chcę, aby drugi element useEffect był uruchamiany po ustawieniu pierwszego elementu useEffect na tekstTransitioning. Podczas usuwania chapterIndexz tablicy zależności pojawia się błąd: „React Hook useEffect ma brakującą zależność:„ ChapterIndex ”. Dołącz go lub usuń tablicę zależności. '
Odpowiedzi
useEffectprzyjmuje 2 argumenty. pierwsza to funkcja do wywołania, a druga to tablica zmiennych zwana tablicą zależności. drugi argument używany do wywołania efektu użycia, gdy jedna ze zmiennych w tablicy się zmienia. więc jeśli nie chcesz useEffectbyć wywoływany po zmianie określonej zmiennej, nie przekazuj jej w tablicy zależności. Twój kod powinien wyglądać tak:
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]
Myślę, że useEffectwywołanie jednego wyzwalania drugiego nie jest zbyt wydajne, ale może nie widzę całego obrazu
Musisz usunąć „sectionIndex” z tablicy w drugim useEffect. Tak więc przy pierwszym uruchomieniu useEffect zaktualizuje parametr „textTransitioning”, który spowoduje drugi wyzwalacz useEffect.
Aby uzyskać bardziej warunkowe wykonanie useEffect, możesz odwołać się https://reactjs.org/docs/hooks-effect.html