Home  >  Article  >  Web Front-end  >  Implementation of React Event event registration

Implementation of React Event event registration

不言
不言Original
2018-07-20 11:22:001555browse

This article introduces to you the implementation of React Event event registration. It has certain reference value. Friends in need can refer to it.

The event handling of React elements is very similar to that of DOM elements. But there is a little grammatical difference:

  • React event binding properties are named in camel case instead of lowercase.

  • If you use JSX syntax, you need to pass in a function as the event processing function instead of a string (the way DOM elements are written)

And React itself implements a synthetic event internally. When using React, you usually do not need to use addEventListener to add a listener to a created DOM element. You only need to provide a listener when the element is initially rendered.

Let’s take a look at how this is implemented

The React event mechanism is divided into event registration and event distribution, two parts

Event registration

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

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

In the above code, onClick is passed in as a props and a handleClick is passed in. When the component is updated and mounted, the props will be processed. The process is as follows:
Implementation of React Event event registration

Core code:
When ReactDOMComponent.js is loading components (mountComponent) and updating (updateComponent), call the _updateDOMProperties method to props Processing:

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,
  });
}

Look at the binding method

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(...);
      }
      ...
  },

Go to the end actually It is doc.addEventLister(event, callback, false);

It can be seen that all events are bound to the document
So the events are triggered by the dispatchEvent method of ReactEventListener

Callback event storage

listenerBank

react maintains a listenerBank variable to save the callbacks of all bound events.
Return to the previous method of registering events

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,
  });
}

When the binding is completed, putListener will be executed.

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 is only instantiated once per React. In other words, the callbacks for all events in the project group will be stored in the unique listenerBank.

Related recommendations:

Use of React: State management inside React components

The above is the detailed content of Implementation of React Event event registration. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn