Heim  >  Artikel  >  Web-Frontend  >  Implementierung der React Event-Ereignisregistrierung

Implementierung der React Event-Ereignisregistrierung

不言
不言Original
2018-07-20 11:22:001556Durchsuche

Dieser Artikel stellt Ihnen die Implementierung der React Event-Ereignisregistrierung vor. Er hat einen gewissen Referenzwert.

Die Ereignisbehandlung von React-Elementen ist der von DOM-Elementen sehr ähnlich. Es gibt jedoch einen kleinen grammatikalischen Unterschied:

  • React-Event-Bindungseigenschaften werden in Kamel- und nicht in Kleinbuchstaben benannt.

  • Wenn Sie JSX-Syntax verwenden, müssen Sie eine Funktion als Ereignishandler anstelle einer Zeichenfolge übergeben (wie DOM-Elemente geschrieben werden)

Und React selbst implementiert intern ein synthetisches Ereignis. Wenn Sie React verwenden, müssen Sie normalerweise nicht addEventListener verwenden, um einem erstellten DOM-Element einen Listener hinzuzufügen. Sie müssen nur dann einen Listener bereitstellen, wenn das Element zum ersten Mal gerendert wird.

Sehen wir uns an, wie dies implementiert wird

Der React-Ereignismechanismus ist in zwei Teile unterteilt: Ereignisregistrierung und Ereignisverteilung

Ereignisregistrierung

// 事件绑定
function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
}

  return (
    <a>
      Click me
    </a>
  );

Im obigen Code wird onClick in einem handleClick als Requisiten übergeben. Wenn die Komponente aktualisiert und gemountet wird, werden die Requisiten wie folgt verarbeitet:


Implementierung der React Event-Ereignisregistrierung

Kerncode:

Wenn
ReactDOMComponent.js das Laden (mountComponent) und Aktualisieren (updateComponent) von Komponenten durchführt, rufen Sie die Methode auf, um Requisiten zu verarbeiten:_updateDOMProperties

ReactDOMComponent.js

_updateDOMProperties: function(lastProps, nextProps, transaction) {
...
if (registrationNameModules.hasOwnProperty(propKey)) {
        if (nextProp) {
          // 如果传入的是事件,去注册事件
          enqueuePutListener(this, propKey, nextProp, transaction);
        } else if (lastProp) {
          deleteListener(this, propKey);
        }
      } 
...
}

// 注册事件
function enqueuePutListener(inst, registrationName, listener, transaction) {
  var containerInfo = inst._nativeContainerInfo;
  var doc = containerInfo._ownerDocument;
    ...
    // 去doc上注册
  listenTo(registrationName, doc);
    // 事务结束之后 putListener
  transaction.getReactMountReady().enqueue(putListener, {
    inst: inst,
    registrationName: registrationName,
    listener: listener,
  });
}

Sehen Sie sich die Bindungsmethode an

ReactBrowserEventEmitter.js

listento

//registrationName:需要绑定的事件
//当前component所属的document,即事件需要绑定的位置
listenTo: function (registrationName, contentDocumentHandle) {
    var mountAt = contentDocumentHandle;
    //获取当前document上已经绑定的事件
    var isListening = getListeningForDocument(mountAt);
    ...
      if (...) {
      //冒泡处理  
      ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(...);
      } else if (...) {
        //捕捉处理
        ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(...);
      }
      ...
  },
Am Ende ist es tatsächlich ein Dokument. addEventLister (event, callback, false);

Sie können sehen, dass alle Ereignisse an das Dokument gebunden sind

Die Ereignisse werden also durch die DispatchEvent-Methode von ReactEventListener ausgelöst

Speicherung von Rückrufereignissen

listenerBank

react verwaltet eine listenerBank-Variable, um die Rückrufe aller gebundenen Ereignisse zu speichern.

Kehren Sie zur vorherigen Methode zum Registrieren von Ereignissen zurück

function enqueuePutListener(inst, registrationName, listener, transaction) {
  var containerInfo = inst._nativeContainerInfo;
  var doc = containerInfo._ownerDocument;
  if (!doc) {
    // Server rendering.
    return;
  }
  listenTo(registrationName, doc);
  transaction.getReactMountReady().enqueue(putListener, {
    inst: inst,
    registrationName: registrationName,
    listener: listener,
  });
}
Wenn die Bindung abgeschlossen ist, wird putListener ausgeführt.

var listenerBank = {};
var getDictionaryKey = function (inst) {
//inst为组建的实例化对象
//_rootNodeID为组件的唯一标识
  return '.' + inst._rootNodeID;
}
var EventPluginHub = {
//inst为组建的实例化对象
//registrationName为事件名称
//listner为我们写的回调函数,也就是列子中的this.autoFocus
  putListener: function (inst, registrationName, listener) {
    ...
    var key = getDictionaryKey(inst);
    var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {});
    bankForRegistrationName[key] = listener;
    ...
  }
}
EventPluginHub wird nur einmal pro React instanziiert. Mit anderen Worten: Die Rückrufe für alle Ereignisse in der Projektgruppe werden in der eindeutigen listenerBank gespeichert.

Verwandte Empfehlungen:

Verwendung von React: Zustandsverwaltung innerhalb von React-Komponenten

Das obige ist der detaillierte Inhalt vonImplementierung der React Event-Ereignisregistrierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn