В React порядок выполнения useEffect и отписки от него зависит от жизненного цикла компонентов. Вот как это работает: Монтирование компонентов: Сначала монтируется компонент A. Затем монтируется компонент B. Наконец, монтируется компонент C. При монтировании компонента useEffect выполняется после рендеринга компонента. Таким образом, порядок выполнения useEffect будет следующим: useEffect компонента C useEffect компонента B useEffect компонента A Размонтирование компонентов: Сначала размонтируется компонент A. Затем размонтируется компонент B. Наконец, размонтируется компонент C. При размонтировании компонента вызывается функция очистки, возвращаемая из useEffect. Таким образом, порядок выполнения функции очистки будет следующим: Функция очистки компонента A Функция очистки компонента B Функция очистки компонента C Таким образом, при монтировании компоненты useEffect выполняются от самого вложенного компонента к самому внешнему, а при размонтировании функции очистки выполняются в обратном порядке - от самого внешнего компонента к самому вложенному. надеюсь не слишком сложно описал)
В React порядок выполнения useEffect и отписки от него зависит от жизненного цикла компонентов. Вот как это работает: Монтирование компонентов: Сначала монтируется компонент A. Затем монтируется компонент B. Наконец, монтируется компонент C. При монтировании компонента useEffect выполняется после рендеринга компонента. Таким образом, порядок выполнения useEffect будет следующим: useEffect компонента C useEffect компонента B useEffect компонента A Размонтирование компонентов: Сначала размонтируется компонент A. Затем размонтируется компонент B. Наконец, размонтируется компонент C. При размонтировании компонента вызывается функция очистки, возвращаемая из useEffect. Таким образом, порядок выполнения функции очистки будет следующим: Функция очистки компонента A Функция очистки компонента B Функция очистки компонента C Таким образом, при монтировании компоненты useEffect выполняются от самого вложенного компонента к самому внешнему, а при размонтировании функции очистки выполняются в обратном порядке - от самого внешнего компонента к самому вложенному.
Я не поленился проверить и у меня получился такой порядок: При первом рендере @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 функции начиная с самой глубоко вложенной
10:40 Снизу вверх. Если стрикт мод будет включен, то useEffect в дев моде будет вызываться дважды, следовательно при монтировании отработает useEffect снизу вверх, потом useEffect вызовется еще раз, где сначала вызовутся return функции, а потом снова useEffect
я всегда стараюсь минимизировать использование этого хука, так глубоко не копал, довольствовался пониманием что юзЭффект вызывается после отрисовки компонента. По задаче - раз компоненты вызываются от родителя до детей, то и в том же порядке должны вызываться эффекты, согласно вашей схемы
сначала clean up а потом функция в юзефект?то есть сначала идет отписка от предидущего собития(которое было в прошлом рендере) а потом подписка на событие в текущем рендере?
useEffect будут вызываться в обратном порядке: сначала у детей, потом у родителей. если перерендер, то сначала отработают cleanup функции от детей к родителям, а потом функции эффекта. но это только в том случае, если массив зависимостей изменился. если не изменился, то при ререндере эффект не отработает
А про React.memo будет или может общее видео про оптимизацию, мол когда надо прям использовать useCallbeck и т.п., а когда их использование будет излишним ?)
Приветствую. Смотря, что вас интересует. На моем сайте mishanep.com вы можете найти как ссылки на мои видео курсы, так и информацию о частном обучении (включая то, как со мной связаться).
А расскажи пожалуйста, насколько корректно в useEffect в зависимости не передавать часть переменных которые используются в useEffect. Линтер ругается если так делать и на сайте react пишут что если не передать все переменные и свойства в useEffect то они могут быть не актуальны во время срабатывания useEffect. На практике, бывают кейсы что нужно вызывать эффект только при изменении определенной переменной, пробовал не включать все зависимости, проблем не было.
Приветствую! Линтер требует включения всех переменных, используемых в теле эффекта. Это так. На моей практике встречались случаи, когда массив зависимостей был неполный и это приводило к нежелательным сайд-эффектам. Но верно и другое, иногда на проектах сознательно не добавляют переменную в массив зависимости, чтобы избежать конкретного поведения. Как частный пример - пустой массив зависимостей, когда мы хотим выполнить эффект лишь один раз (линтер всё равно будет требовать наполнить массив всеми переменными).
Михаил, подскажите пожалуйста, достаточно ли будет ноутбука с диагональю дисплея 13,6 дюймов для обучения/просмотра лекций. При серьёзных задачах планируется подключать монитор 27 дюймов.
А зачем при updated возвращать cleanup функцию если мы можем прописать какое-то действие просто в эффекте? Я думал cleanup вызывается только при размонтировании компонента
Если у вас, например, в эффекте запускается таймер, то без очистки у вас может получиться непредсказуемое количество таймеров. Поэтому во избежание дублирования эффект запускает логику в обновившихся реалиях.
⬇При монтировании компонентов useEffect вызывается для каждого компонента в порядке сверху вниз (родитель -> ребёнок). ⬆При размонтировании компонента происходит вызов функции очистки (cleanUp), начиная с самого внутреннего компонента и двигаясь вверх.
@@ДмитрийГусаров-к5о Строго говоря, useEffect работает через postMessage в requestAnimationFrame, чтобы быть уверенным что он отработает строго после отрисовки
9:30 Точно опечатки нет? Разве в случае Unmounted --> "Возвращалась cleanUp" --> нет --> "Вызов clenUp", а если "да", то End? По-моему там местами "да" и "нет" возле стрелочек перепутаны
Вы такие темы сложные поднимаете, я вот вообще ума не приложу зачем знать какой то жизненный цикл такой узкой специализированной вещи как реакт) Объясните пожалуйста
@@BOCbMOU забавный ты. Каким чудом функция клинап вызовется первой если она даже не попала в стек вызовов? Что бы клинап вызвался сначала должна вызваться функция монтирования компонента.
В React порядок выполнения useEffect и отписки от него зависит от жизненного цикла компонентов. Вот как это работает:
Монтирование компонентов:
Сначала монтируется компонент A.
Затем монтируется компонент B.
Наконец, монтируется компонент C.
При монтировании компонента useEffect выполняется после рендеринга компонента.
Таким образом, порядок выполнения useEffect будет следующим:
useEffect компонента C
useEffect компонента B
useEffect компонента A
Размонтирование компонентов:
Сначала размонтируется компонент A.
Затем размонтируется компонент B.
Наконец, размонтируется компонент C.
При размонтировании компонента вызывается функция очистки, возвращаемая из useEffect. Таким образом, порядок выполнения функции очистки будет следующим:
Функция очистки компонента A
Функция очистки компонента B
Функция очистки компонента C
Таким образом, при монтировании компоненты useEffect выполняются от самого вложенного компонента к самому внешнему, а при размонтировании функции очистки выполняются в обратном порядке - от самого внешнего компонента к самому вложенному.
надеюсь не слишком сложно описал)
Благодарю, очень понятно)
Много читал про него. Везде правильно пишут, как надо. Теперь же увидел, почему так надо, и все затыки пропали. Браво, Михаил!
Пример как вызываются компоненты на монтирование:
test
C effect
B effect
A effect
Пример как вызываются компоненты на размонтирование
A unmount callback
B unmount callback
C unmount callback
В React порядок выполнения useEffect и отписки от него зависит от жизненного цикла компонентов. Вот как это работает:
Монтирование компонентов:
Сначала монтируется компонент A.
Затем монтируется компонент B.
Наконец, монтируется компонент C.
При монтировании компонента useEffect выполняется после рендеринга компонента. Таким образом, порядок выполнения useEffect будет следующим:
useEffect компонента C
useEffect компонента B
useEffect компонента A
Размонтирование компонентов:
Сначала размонтируется компонент A.
Затем размонтируется компонент B.
Наконец, размонтируется компонент C.
При размонтировании компонента вызывается функция очистки, возвращаемая из useEffect. Таким образом, порядок выполнения функции очистки будет следующим:
Функция очистки компонента A
Функция очистки компонента B
Функция очистки компонента C
Таким образом, при монтировании компоненты useEffect выполняются от самого вложенного компонента к самому внешнему, а при размонтировании функции очистки выполняются в обратном порядке - от самого внешнего компонента к самому вложенному.
Я не поленился проверить и у меня получился такой порядок:
При первом рендере
@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 функции начиная с самой глубоко вложенной
@@ДмитрийЧеркашин-р5л да, все верно. Я имел ввиду когда вызывается useEffect. У нас все совпадает.
@@VladislavWebDev речь про еффекты а не про монтирование, УМНЭК😆
Спасибо вам Михаил за ваш труд!
Очень полезное видео. Спасибо большое
Спасибо, очень познавательно!
10:40 Снизу вверх. Если стрикт мод будет включен, то useEffect в дев моде будет вызываться дважды, следовательно при монтировании отработает useEffect снизу вверх, потом useEffect вызовется еще раз, где сначала вызовутся return функции, а потом снова useEffect
Кстати одна из лучших презентаций по useEffect
Михаил, прикольно фотка френдли на видео
я всегда стараюсь минимизировать использование этого хука, так глубоко не копал, довольствовался пониманием что юзЭффект вызывается после отрисовки компонента.
По задаче - раз компоненты вызываются от родителя до детей, то и в том же порядке должны вызываться эффекты, согласно вашей схемы
сначала clean up а потом функция в юзефект?то есть сначала идет отписка от предидущего собития(которое было в прошлом рендере) а потом подписка на событие в текущем рендере?
Да.
useEffect будут вызываться в обратном порядке: сначала у детей, потом у родителей. если перерендер, то сначала отработают cleanup функции от детей к родителям, а потом функции эффекта. но это только в том случае, если массив зависимостей изменился. если не изменился, то при ререндере эффект не отработает
А как без useEffect если некоторые хуки просят его использовать!
Для новичков - отлично!
Все зависит от архитектуры проекта (как ее выстроил программист) Для запросов досточно сделать 1 компонент в котором будет 1 useEffect.
SubChild useEffect -> Child useEffect -> App useEffect -> SubChild cleanUp-> Child cleanUp -> App cleanUp
"вот вам задачка на дом"
Спасибо! Нам только задач и не хватало. Заходишь на канал получить ответ, а тут на тебе вопрос на дом.
так а варианты чтобы не использовать юзэффект в первую очередь для запросов?
Есть хорошая статья на официальном сайте о примерах, когда эффект не нужен
react.dev/learn/you-might-not-need-an-effect
А про React.memo будет или может общее видео про оптимизацию, мол когда надо прям использовать useCallbeck и т.п., а когда их использование будет излишним ?)
У меня на канале уже есть видео про use callback и случаи его использования :)
@@mishanep ооо, супер, тогда пожалуй пойду поищу его)
@@mishanepКруто, надо будет глянуть
Здравстуйте, как с вами связаться насчет обучения?
Приветствую. Смотря, что вас интересует. На моем сайте mishanep.com вы можете найти как ссылки на мои видео курсы, так и информацию о частном обучении (включая то, как со мной связаться).
А расскажи пожалуйста, насколько корректно в useEffect в зависимости не передавать часть переменных которые используются в useEffect. Линтер ругается если так делать и на сайте react пишут что если не передать все переменные и свойства в useEffect то они могут быть не актуальны во время срабатывания useEffect. На практике, бывают кейсы что нужно вызывать эффект только при изменении определенной переменной, пробовал не включать все зависимости, проблем не было.
Приветствую!
Линтер требует включения всех переменных, используемых в теле эффекта. Это так. На моей практике встречались случаи, когда массив зависимостей был неполный и это приводило к нежелательным сайд-эффектам. Но верно и другое, иногда на проектах сознательно не добавляют переменную в массив зависимости, чтобы избежать конкретного поведения. Как частный пример - пустой массив зависимостей, когда мы хотим выполнить эффект лишь один раз (линтер всё равно будет требовать наполнить массив всеми переменными).
Михаил, подскажите пожалуйста, достаточно ли будет ноутбука с диагональю дисплея 13,6 дюймов для обучения/просмотра лекций. При серьёзных задачах планируется подключать монитор 27 дюймов.
Я бы сказал, всё индивидуально. Я пользуюсь 13.3 дисплеем для многих задач, когда надо подключаю экран. Но знаю людей, кому 13-ка маловата.
@@mishanep спасибо большое за ответ.
А зачем при updated возвращать cleanup функцию если мы можем прописать какое-то действие просто в эффекте? Я думал cleanup вызывается только при размонтировании компонента
Если у вас, например, в эффекте запускается таймер, то без очистки у вас может получиться непредсказуемое количество таймеров. Поэтому во избежание дублирования эффект запускает логику в обновившихся реалиях.
⬇При монтировании компонентов useEffect вызывается для каждого компонента в порядке сверху вниз (родитель -> ребёнок).
⬆При размонтировании компонента происходит вызов функции очистки (cleanUp), начиная с самого внутреннего компонента и двигаясь вверх.
эффект не всегда отрабатывает асинхронно, а в 18 версии чаще синхронно чем асинхронно
@@ДмитрийГусаров-к5о Строго говоря, useEffect работает через postMessage в requestAnimationFrame, чтобы быть уверенным что он отработает строго после отрисовки
честно говоря сложно сконцентрироваться на изображении. было бы лучше показывать код в редакторе с подсветкой
9:30 Точно опечатки нет? Разве в случае Unmounted --> "Возвращалась cleanUp" --> нет --> "Вызов clenUp", а если "да", то End? По-моему там местами "да" и "нет" возле стрелочек перепутаны
Там правильно, cleanUp вызывается, если есть. Если нет, то не вызывается
Имеется ввиду возвращалась ли cleanUp в useEffect, то есть существует ли у нас cleanUp вообще
Вы такие темы сложные поднимаете, я вот вообще ума не приложу зачем знать какой то жизненный цикл такой узкой специализированной вещи как реакт) Объясните пожалуйста
Для кого-то Реакт - это основной инструмент. Тогда его надо знать хорошо.
А что значит выражение "была cleanUp функция или не была"?
return () => {} в useEffect называется cleanUp функцией, в ней делают отписки от всяких обработчиков, интервалов и тд...
Это означает передал ли разработчик эту clean up функции или же не передавал, она же опциональная
Другими словами, присутствовала ли cleanUp функция в определенном useEffect'е или нет.
Честно говоря не проверял, но скорее всего сначала все return'ы сверху вниз, а потом все эффекты снизу вверх. Правильно?
Наоборот
@@victormog Сначала все clearUp снизу вверх, потом все эффекты снизу вверх
@@menelaus365 Да
Михаилу спасибо
привет всем лентяям, вот код:
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
Почему у тебя функция клинап вызывается первая? Это не логично, так как ты должен сначала компонент замонтировать.
У тебя какой-то свой реакт. В реальности твой ответ надо перевернуть.
@@BOCbMOU забавный ты.
Каким чудом функция клинап вызовется первой если она даже не попала в стек вызовов?
Что бы клинап вызвался сначала должна вызваться функция монтирования компонента.
@@v.demchenko а ты вообще видишь кому и на что ты отвечаешь?
@@BOCbMOU а, внатуре) Сорян