Анализ исходного кода React (4): система событий

внешний интерфейс исходный код React.js внешний фреймворк
Анализ исходного кода React (4): система событий

Автор напишет три-четыре статьи из серии «Анализ исходного кода React», чтобы объяснить внутренний механизм React. Приглашаю всех обратить внимание на мою учетную запись Nuggets, чтобы вы могли вовремя видеть последние обновления статей.

В предыдущих трех статьях мы объяснили состав и жизненный цикл компонентов реакции, а также механизм setState. На этот раз мы поговорим об обработке событий React.

1. Собственная система событий

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

2. Реагировать на систему событий

Обработка событий React настолько великолепна, что все равно приходится возвращаться к родной системе событий, но ее инкапсуляция очень элегантна. Переходим сразу к выводу:

  • React реализует слой SyntheticEvent для обработки событий.

Что это значит? В деталях React не связывает события с DOM один к одному, как нативные события, а привязывает все события к документу веб-страницы, обрабатывает и распределяет их через унифицированный прослушиватель событий, находит соответствующую функцию обратного вызова и выполняет ее. . Согласно официальной документации, обработчик события будет передавать экземпляр SyntheticEvent, поэтому давайте посмотрим, что такое SyntheticEvent.

3.SyntheticEvent

1. Регистрация на мероприятие

Как упоминалось выше, поскольку React обрабатывает события единообразно, вы должны сначала зарегистрировать функцию триггера событий, написанную программистом, верно? Так где же происходит этот процесс? Потому что мы «привязываем» событие к «DOM компонента», например событие клика:

<Component onClick={this.handleClick}/>

На самом деле, когда этот компонент смонтирован, React уже начал проходитьmountCompoentВнутренний_updateDOMPropertiesМетоды обработки событий. В этом методе выполняетсяenqueuePutListenerспособ регистрации события:

следуй за виноградной лозой,listenToКлюч метода вызывает следующие две функции:

  • trapBubbledEvent
  • trapCapturedEvent

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

в приведенном выше кодеtargetто естьdocument, также видел знакомыйdocument.addEventListenerа такжеdocument.removeEventListener. Именно эта унифицированная привязка событий снижает нагрузку на память.

2. Хранение событий

После того, как функция обратного вызова события, которую мы написали, зарегистрирована, ее необходимо сохранить, чтобы ее можно было вызвать при ее срабатывании. Вход в магазин естьEventPluginHub.putListenerфункция:

Видно, что все callback-функции хранятся в виде двумерных массивов вlistenerBank, по соответствующему компонентуkeyСправляться.

3. Распределение событий

У нас есть четкая регистрация событий и хранилище событий Теперь давайте посмотрим, как React распределяет события и находит соответствующую функцию обратного вызова и выполняет ее при срабатывании события. запись о раздаче вReactDOMEventListener.jsизhandleTopLevelImpl:

Приведенный выше код поясняет процесс: поскольку структура DOM может измениться после выполнения функции обратного вызова события, React сначала сохраняет текущую структуру в виде массива, а затем, в свою очередь, проходит и выполняет ее. вышеуказанной функции_handleTopLevelНаконец, callback-функция обработана, смотрим исходный код:

В коде появляются новые роли:EventPluginHub.extractEvents. Ознакомьтесь с соответствующей информациейextractEventsМетод используется для синтеза событий, то есть для синтеза разных кроссбраузерных событий по разным типам событий.SyntheticEventэкземпляр объекта, напримерSyntheticClickEvent. а такжеEventPluginHubКак следует из названия, это инструментальный плагин, используемый React для синтеза событий:

Видно, что для разных событий React будет использовать разные функциональные плагины, которые все используются внутри посредством внедрения зависимостей. Процесс синтеза событий в React очень утомительный, но его можно обобщить.extractEventsВнутри функция в основном черезswitchФункция различает типы событий и вызывает различные плагины для обработки, чтобы сгенерироватьSyntheticEventпример. Заинтересованные студенты могут узнать об этом самостоятельно.

4. Обработка событий

Идея и обработка событий обработки ReactsetStateИдея похожа, оба используют пакетный метод. наверхуhandleTopLevelВ методе мы видим, что последнее выполнениеrunEventQueueInBatchметод:

    //事件进入队列
    EventPluginHub.enqueueEvents(events);
    //...
    EventPluginHub.processEventQueue(false);

СмотретьprocessEventQueue:

Приведенный выше код перебирает события в очереди и вводитexecuteDispatchesAndReleaseSimulated:

event.constructor.release(event);

Эта строка кода освобождает синтетические события React, чтобы уменьшить нагрузку на память. Основная запись обработки событий находится вexecuteDispatchesInOrder:

var dispatchListeners = event._dispatchListeners;
var dispatchInstances = event._dispatchInstances;

executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]);

Важным кодом являются эти три строки,dispatchListenersфункция обратного вызова события,dispatchInstancesявляется соответствующим компонентом, передайте эти параметры вexecuteDispatchназад:

function executeDispatch(event, simulated, listener, inst) {
    var type = event.type || 'unknown-event';
    ReactErrorUtils.invokeGuardedCallback(type, listener, event);
}

а такжеinvokeGuardedCallbackЭто довольно просто:

function invokeGuardedCallback(name, func, a) {
    func(a);
}

надfunc(a)На самом деле этоlistener(event), а затем прослеживается, этоdispatchListeners(dispatchInstances), что также объясняет, почему наша функция обратного вызова события React может получать нативные события.

4. Резюме

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

рассмотрение:
«Анализ исходного кода React (1): внедрение и установка компонентов»
«Анализ исходного кода React (2): типы и жизненные циклы компонентов»
«Анализ исходного кода React (3): подробные транзакции и очереди»
Контактный адрес электронной почты: sssyoki@foxmail.com