Чи слід використовувати один або кілька useEffect у компоненті?


105

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

  • як одноразовий ефект
  • або кілька ефектів використання

Що краще з точки зору продуктивності та архітектури?

Відповіді:


162

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

По-перше , у вас може виникнути ситуація, коли вам потрібно додати прослуховувач подій під час початкового монтування та очистити їх при відключенні, а інший випадок, коли певний прослуховувач потрібно очистити та повторно додати при зміні реквізиту. У такому випадку, використовуючи два різні 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])

1
а як щодо проміжної ситуації між другим і третім прикладами вище?: у вас є логіка, яка працює, коли змінюється підмножина стану / реквізиту, але кожен має окрему логіку, яка повинна запускатися на додаток до загального коду, який потрібно запустити? Ви не використовували б [](оскільки це все ще лише підмножина стану / реквізиту, на який ви чекаєте змін), але ви також хотіли б повторно використовувати код. Чи використовуєте ви окремий useEffectsкод і вкладаєте спільний код у функцію, яку вони кожен окремо викликають?
ecoe

2
Як випливає з відповіді нижче, команда React пропонує розділити хуки за занепокоєнням, тож ви розділите його на кілька useEffectдзвінків.
hakazvaka

28
Мені подобається, як ви писали useCase.
VerticalGrain

Чи завжди вони запускаються в порядку їх визначення? тобто ефект1 завжди називається спочатку, потім ефект2?
computrius

1
@computrius Так ,React will apply every effect used by the component, in the order they were specified.
серпень Джанс

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.