Должен ли я использовать один или несколько useEffect в компоненте?

102

У меня есть несколько побочных эффектов, и я хочу знать, как их организовать:

  • как одноразовое использование
  • или несколько useEffects

Что лучше с точки зрения производительности и архитектуры?

Вадим
источник

Ответы:

159

Шаблон, которому нужно следовать, зависит от вашего варианта использования.

Во-первых , у вас может быть ситуация, когда вам нужно добавить прослушиватель событий во время первоначального монтирования и очистить их при размонтировании, а также другой случай, когда конкретный слушатель необходимо очистить и повторно добавить при изменении свойства. В таком случае использование двух разных useEffect лучше для сохранения соответствующей логики вместе, а также для повышения производительности.

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

Во-вторых: может быть случай, когда вам нужно инициировать вызов API или какой-либо другой побочный эффект, когда какое-либо состояние или реквизиты меняются среди набора. В таком случае useEffectхорошей идеей будет сингл с соответствующими значениями для мониторинга.

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

Третий: Третий случай, когда вам нужно предпринять разные действия при изменении разных значений. В таком случае разделите соответствующие сравнения на разныеuseEffects

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

useEffect(() => {
   // another side-effect on change of stateX or stateY 
}, [stateX, stateY])
Шубхам Хатри
источник
как насчет золотой середины между вторым и третьим примером выше ?: у вас есть логика, которая запускается при изменении подмножества состояний / реквизитов, но у каждого есть отдельная логика, которая должна выполняться в дополнение к некоторому общему коду, который необходимо запустить? Вы бы не стали использовать [](потому что это все еще только подмножество состояний / свойств, для которых вы ожидаете изменений), но вы также хотели бы повторно использовать код. Вы используете отдельный useEffectsи помещаете общий код в функцию, которую каждый из них вызывает отдельно?
ecoe
Как следует из приведенного ниже ответа, команда React предлагает разделить хуки по проблемам, чтобы вы могли разделить их на несколько useEffectвызовов.
hakazvaka
28
Мне нравится, как вы написали useCase.
VerticalGrain
Всегда ли они запускаются в порядке их определения? т.е. сначала всегда вызывается эффект1, а затем эффект2?
computrius