useEffect подробно - как работает, когда вызываются эффекты

แชร์
ฝัง
  • เผยแพร่เมื่อ 25 พ.ย. 2024

ความคิดเห็น • 69

  • @muradatabalov9281
    @muradatabalov9281 3 หลายเดือนก่อน +22

    В React порядок выполнения useEffect и отписки от него зависит от жизненного цикла компонентов. Вот как это работает:
    Монтирование компонентов:
    Сначала монтируется компонент A.
    Затем монтируется компонент B.
    Наконец, монтируется компонент C.
    При монтировании компонента useEffect выполняется после рендеринга компонента.
    Таким образом, порядок выполнения useEffect будет следующим:
    useEffect компонента C
    useEffect компонента B
    useEffect компонента A
    Размонтирование компонентов:
    Сначала размонтируется компонент A.
    Затем размонтируется компонент B.
    Наконец, размонтируется компонент C.
    При размонтировании компонента вызывается функция очистки, возвращаемая из useEffect. Таким образом, порядок выполнения функции очистки будет следующим:
    Функция очистки компонента A
    Функция очистки компонента B
    Функция очистки компонента C
    Таким образом, при монтировании компоненты useEffect выполняются от самого вложенного компонента к самому внешнему, а при размонтировании функции очистки выполняются в обратном порядке - от самого внешнего компонента к самому вложенному.
    надеюсь не слишком сложно описал)

    • @just_music-c6r
      @just_music-c6r 3 หลายเดือนก่อน +1

      Благодарю, очень понятно)

  • @Dmitrii_Bashkatov
    @Dmitrii_Bashkatov 3 หลายเดือนก่อน +3

    Много читал про него. Везде правильно пишут, как надо. Теперь же увидел, почему так надо, и все затыки пропали. Браво, Михаил!

  • @v.demchenko
    @v.demchenko 3 หลายเดือนก่อน +10

    Пример как вызываются компоненты на монтирование:

    test

    C effect
    B effect
    A effect
    Пример как вызываются компоненты на размонтирование
    A unmount callback
    B unmount callback
    C unmount callback

    • @muradatabalov9281
      @muradatabalov9281 3 หลายเดือนก่อน +5

      В React порядок выполнения useEffect и отписки от него зависит от жизненного цикла компонентов. Вот как это работает:
      Монтирование компонентов:
      Сначала монтируется компонент A.
      Затем монтируется компонент B.
      Наконец, монтируется компонент C.
      При монтировании компонента useEffect выполняется после рендеринга компонента. Таким образом, порядок выполнения useEffect будет следующим:
      useEffect компонента C
      useEffect компонента B
      useEffect компонента A
      Размонтирование компонентов:
      Сначала размонтируется компонент A.
      Затем размонтируется компонент B.
      Наконец, размонтируется компонент C.
      При размонтировании компонента вызывается функция очистки, возвращаемая из useEffect. Таким образом, порядок выполнения функции очистки будет следующим:
      Функция очистки компонента A
      Функция очистки компонента B
      Функция очистки компонента C
      Таким образом, при монтировании компоненты useEffect выполняются от самого вложенного компонента к самому внешнему, а при размонтировании функции очистки выполняются в обратном порядке - от самого внешнего компонента к самому вложенному.

    • @ДмитрийЧеркашин-р5л
      @ДмитрийЧеркашин-р5л 3 หลายเดือนก่อน +3

      Я не поленился проверить и у меня получился такой порядок:
      При первом рендере
      @MOUNT A
      @MOUNT B
      @MOUNT C
      @EFFECT C
      @EFFECT B
      @EFFECT A
      При обновлении зависимости в useEffect
      @MOUNT A
      @MOUNT B
      @MOUNT C
      @CLEANUP C
      @CLEANUP B
      @CLEANUP A
      @EFFECT C
      @EFFECT B
      @EFFECT A
      При размонтировании
      @CLEANUP A
      @CLEANUP B
      @CLEANUP C
      Вся суть заключается в том что при обновлении зависимости сначала вызываеются все cleanUp функции начиная с самой глубоко вложенной

    • @v.demchenko
      @v.demchenko 3 หลายเดือนก่อน

      @@ДмитрийЧеркашин-р5л да, все верно. Я имел ввиду когда вызывается useEffect. У нас все совпадает.

    • @v.demchenko
      @v.demchenko 2 หลายเดือนก่อน

      @@VladislavWebDev речь про еффекты а не про монтирование, УМНЭК😆

  • @FF-gq3hm
    @FF-gq3hm 3 หลายเดือนก่อน

    Спасибо вам Михаил за ваш труд!

  • @СергейСульженко-ф9я
    @СергейСульженко-ф9я 3 หลายเดือนก่อน

    Очень полезное видео. Спасибо большое

  • @NikOroferov
    @NikOroferov 3 หลายเดือนก่อน

    Спасибо, очень познавательно!

  • @MykytaSydorenko-u5n
    @MykytaSydorenko-u5n 3 หลายเดือนก่อน +4

    10:40 Снизу вверх. Если стрикт мод будет включен, то useEffect в дев моде будет вызываться дважды, следовательно при монтировании отработает useEffect снизу вверх, потом useEffect вызовется еще раз, где сначала вызовутся return функции, а потом снова useEffect

  • @agag5083
    @agag5083 3 หลายเดือนก่อน

    Кстати одна из лучших презентаций по useEffect

  • @АлександрЧеремных-у2щ
    @АлександрЧеремных-у2щ 3 หลายเดือนก่อน

    Михаил, прикольно фотка френдли на видео

  • @un_defined
    @un_defined 3 หลายเดือนก่อน

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

  • @Jen13022
    @Jen13022 3 หลายเดือนก่อน +3

    сначала clean up а потом функция в юзефект?то есть сначала идет отписка от предидущего собития(которое было в прошлом рендере) а потом подписка на событие в текущем рендере?

    • @mishanep
      @mishanep  3 หลายเดือนก่อน

      Да.

  • @INetreba
    @INetreba 3 หลายเดือนก่อน +2

    useEffect будут вызываться в обратном порядке: сначала у детей, потом у родителей. если перерендер, то сначала отработают cleanup функции от детей к родителям, а потом функции эффекта. но это только в том случае, если массив зависимостей изменился. если не изменился, то при ререндере эффект не отработает

  • @СергейК-б6н
    @СергейК-б6н 3 หลายเดือนก่อน

    А как без useEffect если некоторые хуки просят его использовать!

  • @victormog
    @victormog 3 หลายเดือนก่อน

    Для новичков - отлично!

  • @v.demchenko
    @v.demchenko 3 หลายเดือนก่อน

    Все зависит от архитектуры проекта (как ее выстроил программист) Для запросов досточно сделать 1 компонент в котором будет 1 useEffect.

  • @gloomyrobust
    @gloomyrobust 3 หลายเดือนก่อน

    SubChild useEffect -> Child useEffect -> App useEffect -> SubChild cleanUp-> Child cleanUp -> App cleanUp

  • @nikewhite4471
    @nikewhite4471 3 หลายเดือนก่อน +1

    "вот вам задачка на дом"
    Спасибо! Нам только задач и не хватало. Заходишь на канал получить ответ, а тут на тебе вопрос на дом.

  • @РоманРоман-у7т
    @РоманРоман-у7т 3 หลายเดือนก่อน

    так а варианты чтобы не использовать юзэффект в первую очередь для запросов?

    • @mishanep
      @mishanep  3 หลายเดือนก่อน +1

      Есть хорошая статья на официальном сайте о примерах, когда эффект не нужен
      react.dev/learn/you-might-not-need-an-effect

  • @pulyvil3909
    @pulyvil3909 3 หลายเดือนก่อน

    А про React.memo будет или может общее видео про оптимизацию, мол когда надо прям использовать useCallbeck и т.п., а когда их использование будет излишним ?)

    • @mishanep
      @mishanep  3 หลายเดือนก่อน

      У меня на канале уже есть видео про use callback и случаи его использования :)

    • @pulyvil3909
      @pulyvil3909 3 หลายเดือนก่อน

      @@mishanep ооо, супер, тогда пожалуй пойду поищу его)

    • @pulyvil3909
      @pulyvil3909 3 หลายเดือนก่อน

      ​@@mishanepКруто, надо будет глянуть

  • @ЭзизК
    @ЭзизК 3 หลายเดือนก่อน

    Здравстуйте, как с вами связаться насчет обучения?

    • @mishanep
      @mishanep  3 หลายเดือนก่อน +2

      Приветствую. Смотря, что вас интересует. На моем сайте mishanep.com вы можете найти как ссылки на мои видео курсы, так и информацию о частном обучении (включая то, как со мной связаться).

  • @Realing29
    @Realing29 2 หลายเดือนก่อน

    А расскажи пожалуйста, насколько корректно в useEffect в зависимости не передавать часть переменных которые используются в useEffect. Линтер ругается если так делать и на сайте react пишут что если не передать все переменные и свойства в useEffect то они могут быть не актуальны во время срабатывания useEffect. На практике, бывают кейсы что нужно вызывать эффект только при изменении определенной переменной, пробовал не включать все зависимости, проблем не было.

    • @mishanep
      @mishanep  2 หลายเดือนก่อน

      Приветствую!
      Линтер требует включения всех переменных, используемых в теле эффекта. Это так. На моей практике встречались случаи, когда массив зависимостей был неполный и это приводило к нежелательным сайд-эффектам. Но верно и другое, иногда на проектах сознательно не добавляют переменную в массив зависимости, чтобы избежать конкретного поведения. Как частный пример - пустой массив зависимостей, когда мы хотим выполнить эффект лишь один раз (линтер всё равно будет требовать наполнить массив всеми переменными).

  • @gedonik
    @gedonik 3 หลายเดือนก่อน

    Михаил, подскажите пожалуйста, достаточно ли будет ноутбука с диагональю дисплея 13,6 дюймов для обучения/просмотра лекций. При серьёзных задачах планируется подключать монитор 27 дюймов.

    • @mishanep
      @mishanep  3 หลายเดือนก่อน

      Я бы сказал, всё индивидуально. Я пользуюсь 13.3 дисплеем для многих задач, когда надо подключаю экран. Но знаю людей, кому 13-ка маловата.

    • @gedonik
      @gedonik 3 หลายเดือนก่อน

      @@mishanep спасибо большое за ответ.

  • @aleksiej3290
    @aleksiej3290 3 หลายเดือนก่อน

    А зачем при updated возвращать cleanup функцию если мы можем прописать какое-то действие просто в эффекте? Я думал cleanup вызывается только при размонтировании компонента

    • @mishanep
      @mishanep  3 หลายเดือนก่อน +1

      Если у вас, например, в эффекте запускается таймер, то без очистки у вас может получиться непредсказуемое количество таймеров. Поэтому во избежание дублирования эффект запускает логику в обновившихся реалиях.

  • @FF-gq3hm
    @FF-gq3hm 3 หลายเดือนก่อน

    ⬇При монтировании компонентов useEffect вызывается для каждого компонента в порядке сверху вниз (родитель -> ребёнок).
    ⬆При размонтировании компонента происходит вызов функции очистки (cleanUp), начиная с самого внутреннего компонента и двигаясь вверх.

  • @ДмитрийГусаров-к5о
    @ДмитрийГусаров-к5о 3 หลายเดือนก่อน +13

    эффект не всегда отрабатывает асинхронно, а в 18 версии чаще синхронно чем асинхронно

    • @funkjoker
      @funkjoker 3 หลายเดือนก่อน

      @@ДмитрийГусаров-к5о Строго говоря, useEffect работает через postMessage в requestAnimationFrame, чтобы быть уверенным что он отработает строго после отрисовки

  • @alexeyfilippov42
    @alexeyfilippov42 3 หลายเดือนก่อน +3

    честно говоря сложно сконцентрироваться на изображении. было бы лучше показывать код в редакторе с подсветкой

  • @MadBlissOff
    @MadBlissOff 3 หลายเดือนก่อน

    9:30 Точно опечатки нет? Разве в случае Unmounted --> "Возвращалась cleanUp" --> нет --> "Вызов clenUp", а если "да", то End? По-моему там местами "да" и "нет" возле стрелочек перепутаны

    • @DubinArtur
      @DubinArtur 3 หลายเดือนก่อน

      Там правильно, cleanUp вызывается, если есть. Если нет, то не вызывается

    • @Dendosha
      @Dendosha 3 หลายเดือนก่อน

      Имеется ввиду возвращалась ли cleanUp в useEffect, то есть существует ли у нас cleanUp вообще

  • @СергейК-б6н
    @СергейК-б6н 3 หลายเดือนก่อน

    Вы такие темы сложные поднимаете, я вот вообще ума не приложу зачем знать какой то жизненный цикл такой узкой специализированной вещи как реакт) Объясните пожалуйста

    • @mishanep
      @mishanep  3 หลายเดือนก่อน

      Для кого-то Реакт - это основной инструмент. Тогда его надо знать хорошо.

  • @_kie
    @_kie 3 หลายเดือนก่อน

    А что значит выражение "была cleanUp функция или не была"?

    • @MykytaSydorenko-u5n
      @MykytaSydorenko-u5n 3 หลายเดือนก่อน +2

      return () => {} в useEffect называется cleanUp функцией, в ней делают отписки от всяких обработчиков, интервалов и тд...

    • @Farruh_13
      @Farruh_13 3 หลายเดือนก่อน +3

      Это означает передал ли разработчик эту clean up функции или же не передавал, она же опциональная

    • @Deivon27
      @Deivon27 3 หลายเดือนก่อน +1

      Другими словами, присутствовала ли cleanUp функция в определенном useEffect'е или нет.

  • @ЭТОЯ-я1ц
    @ЭТОЯ-я1ц 3 หลายเดือนก่อน

    Честно говоря не проверял, но скорее всего сначала все return'ы сверху вниз, а потом все эффекты снизу вверх. Правильно?

    • @victormog
      @victormog 3 หลายเดือนก่อน +2

      Наоборот

    • @menelaus365
      @menelaus365 3 หลายเดือนก่อน +2

      ​@@victormog Сначала все clearUp снизу вверх, потом все эффекты снизу вверх

    • @victormog
      @victormog 3 หลายเดือนก่อน +1

      @@menelaus365 Да

  • @TpyrBo3Db
    @TpyrBo3Db 3 หลายเดือนก่อน +1

    Михаилу спасибо
    привет всем лентяям, вот код:
    function Grandchild() {
    useEffect(() => {
    console.log('Grandchild effect');
    return () => {
    console.log('Grandchild cleanup');
    };
    }, []);
    return Grandchild;
    }
    function Child() {
    useEffect(() => {
    console.log('Child effect');
    return () => {
    console.log('Child cleanup');
    };
    }, []);
    return (

    Child


    );
    }
    function Parent() {
    useEffect(() => {
    console.log('Parent effect');
    return () => {
    console.log('Parent cleanup');
    };
    }, []);
    return (

    Parent


    );
    }
    и ответ
    Grandchild cleanup
    Child cleanup
    Parent cleanup
    Parent effect
    Child effect
    Grandchild effect

    • @v.demchenko
      @v.demchenko 3 หลายเดือนก่อน +2

      Почему у тебя функция клинап вызывается первая? Это не логично, так как ты должен сначала компонент замонтировать.

    • @BOCbMOU
      @BOCbMOU 3 หลายเดือนก่อน +1

      У тебя какой-то свой реакт. В реальности твой ответ надо перевернуть.

    • @v.demchenko
      @v.demchenko 3 หลายเดือนก่อน

      ​@@BOCbMOU забавный ты.
      Каким чудом функция клинап вызовется первой если она даже не попала в стек вызовов?
      Что бы клинап вызвался сначала должна вызваться функция монтирования компонента.

    • @BOCbMOU
      @BOCbMOU 3 หลายเดือนก่อน +1

      @@v.demchenko а ты вообще видишь кому и на что ты отвечаешь?

    • @v.demchenko
      @v.demchenko 3 หลายเดือนก่อน

      @@BOCbMOU а, внатуре) Сорян