Автор напишет три-четыре статьи из серии «Анализ исходного кода 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