Все об использованииЭффект

React.js
Все об использованииЭффект

так какReactРазработчики, можете ли вы ответить на следующие два вопроса:

  1. Для следующих функциональных компонентов:
function Child() {
  useEffect(() => {
    console.log('child');
  }, [])

  return <p>hello</p>;
}

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

  return <Child/>;
}

function App() {
  useEffect(() => {
    console.log('app');
  }, [])

  return <Parent/>;
}

оказывать<App/>Каков порядок печати консоли?

  1. Вызываются ли следующие две функции обратного вызова одновременно?
// componentDidMount生命周期钩子
class App extends React.Component {
  componentDidMount() {
    console.log('hello');
  }
}

// 依赖为[]的useEffect
useEffect(() => {
  console.log('hello');
}, [])

Отвечать:

👉向右滑动翻看答案                                                 1. child -> parent -> app
                                                                2. 不同                                              

На самом деле эти два вопроса рассматриваются отдельно:

  • useEffectисполнительный лист
  • useEffectКак принять участиеReactпроцесс работы

В этой статье мы углубимся в исходный код и познакомим вас с этими знаниями.

Это оuseEffectвсе из.

Порядок выполнения useEffect

ReactИсходный код можно разделить на три части:

  • планировщик: расписание обновлений
  • Координатор: решить, что обновить
  • визуализатор: визуализирует обновленный контент в представлении

Среди них только渲染器Выполняется операция визуализации представления.

Только для среды браузера渲染器сделал бы что-то вродеappendChild,insertBeforeТакойDOMработать.

协调器Как вы решаете, что обновлять?

Ответ: он будет соответствовать контенту, который должен быть обновленfiber(можно понимать как虚拟DOM) отмечены.

эти отмеченыfiberсформирует связанный списокeffectList.

渲染器пройдетeffectList, выполните операцию, соответствующую отметке.

  • НапримерPlacementотметка, соответствующая вставкеDOM

  • НапримерUpdateОтметьте соответствующее обновлениеDOMАтрибуты

useEffectТакже следует тому же принципу работы:

  1. Когда запускается обновление,FunctionComponentвыполняется, выполняется до тех пор, покаuseEffectбудет судить о его втором параметре, когдаdepsЕсть ли изменение.

  2. еслиdepsизменить, тоuseEffectвести перепискуFunctionComponentизfiberЭто будет отмеченоPassive(т.е. тег, который должен выполнить USEFECHECT).

  3. существует渲染器в, траверсeffectListпройти кfiber, нашелPassiveотметить, затем выполнитьuseEffectизdestroy(которыйuseEffectфункция возвращаемого значения функции обратного вызова) иcreate(которыйuseEffectПерезвоните).

Среди них первые два шага происходят в协调器середина.

так,effectListПорядок сборки такойuseEffectисполнительный порядок.

effectList

协调器Рабочий процесс заключается в использовании遍历осуществленный递归. Так что его можно разделить наа такжедва этапа.

мы знаем,идет от корневого узла к листовым узлам,от листового узла до корневого узла.

effectListСборка происходит всцена. так,effectListПорядок также от листовых узлов до самого верха.

useEffectвести перепискуfiberтак какeffectListУзел в , логика вызова которого также следуетобработать.

Теперь у нас достаточно знаний, чтобы ответить на первый вопрос:

из-заэтап изChildприбытьParentприбытьApp, поэтому соответствующийeffectListТоже в том же порядке.

такuseEffectФункции обратного вызова выполняются в том же порядке.

Не используйте аналогию с хуком жизненного цикла для хука

мы новичкиhook, буду использоватьClassComponentАналогия с крючком жизненного циклаhookвремя исполнения.

Так учит даже официальный сайт.

Однако, как мы уже знаем из вышеизложенного,ReactВыполнение следующее:

调度 -- 协调 -- 渲染

Принцип работы, связанный с рендерингом, следующий:

构建effectList -- 遍历effectList执行对应操作

весь процесс и生命周期钩子Это не имеет значения.

Фактически生命周期钩子Просто функция ловушки, прикрепленная к этому процессу.

Итак, лучше начать сReactЗапустите процесс, чтобы понятьuseEffectвремя исполнения.

оказывать

Согласно процессу,effectListБудет в渲染器обработано в.

дляuseEffectНапример, пересечениеeffectList, найдет все содержащиеPassiveотмеченfiber.

выполнить соответствующееuseEffectизdestroy.

всеdestroyПосле выполнения выполнить всеcreate.

Весь процесс выполняется асинхронно после рендеринга страницы.

Чтобы ответить на второй вопрос:

еслиuseEffectизdepsдля[],из-заdepsне изменится, что соответствуетfiberтолько вmountотмечено, когдаPassive.

Это похожеcomponentDidMountиз.

Тем не менее, обработкаPassive effectвыполняется асинхронно после завершения рендеринга, аcomponentDidMountвыполняются синхронно после рендеринга, поэтому они разные.

useEffect и useLayoutEffect

а такжеcomponentDidMountболее похожиuseLayoutEffect, он будет выполняться синхронно после завершения рендеринга.

ВотОнлайн-демонстрация, вы можете поставитьDemoсерединаuseLayoutEffectзаменитьuseEffect, чтобы увидеть их различия.

Суммировать

Благодаря этой статье мы узналиuseEffectполный процесс исполнения.

В этой серии статей будет по-прежнему использоваться метод примеров + исходный код для интерпретации часто используемых бизнес-приложений.Reactхарактеристика.

Электронные книги с открытым исходным кодомДемистификация технологии ReactЛегко изучить исходный код React