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
// 事件绑定 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:
Core code:
When ReactDOMComponent.js is loading components (mountComponent) and updating (updateComponent), call the _updateDOMProperties
method to props Processing:
_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
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
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!