Czy powinienem użyć jednego czy wielu useEffect w komponencie?

118

Mam kilka efektów ubocznych do zastosowania i chcę wiedzieć, jak je zorganizować:

  • jako jednorazowy efekt
  • lub kilka useEffects

Co jest lepsze pod względem wydajności i architektury?

Vadim
źródło

Odpowiedzi:

178

Wzór, którego musisz przestrzegać, zależy od twojego przypadku użycia.

Po pierwsze , możesz mieć sytuację, w której będziesz musiał dodać detektor zdarzeń podczas początkowego montowania i wyczyścić je przy odmontowywaniu, a także inny przypadek, w którym określony odbiornik musi zostać wyczyszczony i ponownie dodany po zmianie właściwości. W takim przypadku użycie dwóch różnych useEffect jest lepsze, aby zachować razem odpowiednią logikę, a także uzyskać korzyści związane z wydajnością

useEffect(() => {
   // adding event listeners on mount here
   return () => {
       // cleaning up the listeners here
   }
}, []);

useEffect(() => {
   // adding listeners everytime props.x changes
   return () => {
       // removing the listener when props.x changes
   }
}, [props.x])

Po drugie: może zaistnieć potrzeba wyzwolenia wywołania API lub jakiegoś innego efektu ubocznego, gdy jakikolwiek stan lub właściwości zmieniają się w zestawie. W takim przypadku useEffectdobrym pomysłem powinien być singiel z odpowiednimi wartościami do monitorowania

useEffect(() => {
    // side effect here on change of any of props.x or stateY
}, [props.x, stateY])

Po trzecie: Trzeci przypadek, w którym musisz podjąć różne działania przy zmianie różnych wartości. W takim przypadku należy rozdzielić odpowiednie porównania na różneuseEffects

useEffect(() => {
   // some side-effect on change of props.x
}, [props.x])

useEffect(() => {
   // another side-effect on change of stateX or stateY 
}, [stateX, stateY])
Shubham Khatri
źródło
1
A co z punktem pośrednim między drugim a trzecim przykładem powyżej ?: masz logikę, która działa, gdy podzbiór stanu / właściwości się zmienia, ale każdy ma oddzielną logikę, która musi działać oprócz jakiegoś wspólnego kodu, który musi działać? Nie używałbyś [](ponieważ to wciąż tylko podzbiór stanów / właściwości, na które czekasz na zmiany), ale chciałbyś również ponownie użyć kodu. Czy używasz osobnego useEffectskodu i umieszczasz wspólny kod w funkcji, którą każdy z nich wywołuje osobno?
ecoe
3
Jak sugeruje poniższa odpowiedź, zespół React sugeruje rozdzielanie haków według obaw, aby podzielić je na wiele useEffectpołączeń.
hakazvaka
33
Podoba mi się sposób, w jaki napisałeś useCase.
VerticalGrain
Czy zawsze są uruchamiane w kolejności ich definicji? tzn. efekt1 jest zawsze wywoływany jako pierwszy, a potem efekt2?
computrius
1
@computrius Tak ,React will apply every effect used by the component, in the order they were specified.
sierpień Janse