I will write three or four articles in the “React source Code Analysis “series, explaining the internal mechanism of React. Welcome everyone to follow my gold mining account, so that you can see the latest article update push in time.

In the previous three articles, we explained the react component’s composition and lifecycle, and the mechanism of setState. This time let’s talk about React.

1. Native event system

We usually listen to the real DOM. For example, at 🌰, if we want to listen for button click events, we can bind the event and the corresponding callback function to the button DOM. Unfortunately, if the page is complex and the event processing frequency is high, then the performance of the page is a test.

React event system

React’s event handling is dizzying and still goes back to the original event system, but it’s elegantly encapsulated. Let’s jump right to the conclusion:

  • React implements the SyntheticEvent layer to handle events

What does that mean? To be specific, React does not one-to-one correspond events to DOM like native events, but binds all events to the document of the web page, which is processed and distributed by unified event listeners, and then finds the corresponding callback function and executes it. According to the official documentation, the event handler will pass an instance of a SyntheticEvent, so let’s take a look at what SyntheticEvent is.

3.SyntheticEvent

1. Event registration

Since React handles events uniformly, you need to register a programmer-written event-triggering function. So where is this process performed? This is because we are “binding” events to the “component DOM”, such as a click event:

<Component onClick={this.handleClick}/>
Copy the code

When this component is mounted, React is already handling events via the _updateDOMProperties method inside mountCompoent. In this method, the enqueuePutListener method is executed to derregister the event:

The listenTo method calls the following two functions:

  • trapBubbledEvent
  • trapCapturedEvent

As readers familiar with the native event system will know from the English translation, two functions are used to handle event capture and event bubbling. Instead of analyzing the logic, let’s look directly inside the two functions:

The code in the target document, also saw the familiar with the document. The addEventListener and document. The removeEventListener. It is this uniform event binding that reduces memory overhead.

2. Event storage

The event callbacks we write need to be stored after registration so that we can call back when triggered. Store entrance is EventPluginHub. PutListener function:

You can see that all callbacks are stored as two-dimensional arrays in listenerBank, managed according to the key corresponding to the component.

3. Event distribution

Event registration and event storage are well known. Now let’s take a look at how React distributes events and finds and executes the corresponding callback function when an event is triggered. Distribution entry in ReactDomEventListener.js handleTopLevelImpl:

React stores the current DOM structure as an array and then iterates through it in sequence, since the event callback may change the DOM structure. The _handleTopLevel of the above function ultimately handles the callback function.

Code in a new role: EventPluginHub extractEvents. The extractEvents method is used to synthesize events, that is, to synthesize different instances of cross-browser SyntheticEvent objects, such as SyntheticClickEvent, depending on the event type. EventPluginHub is the plugin that React uses to synthesize events:

As you can see, React uses different functional plug-ins for different events, all of which are used internally through dependency injection. The React event synthesis process is quite tedious, but the extractEvents function is basically a switch function that distinguishes event types and calls different plug-ins for processing to generate SyntheticEvent instances. If you are interested, you can find out.

4. Event handling

React handles events in a similar way to setState, using a batch approach. In the handleTopLevel method above we see that the runEventQueueInBatch method is finally executed:

    // The event is queued
    EventPluginHub.enqueueEvents(events);
    / /...
    EventPluginHub.processEventQueue(false);
Copy the code

Look at the processEventQueue:

The code above traverse the events in this queue, and into the executeDispatchesAndReleaseSimulated:

event.constructor.release(event);
Copy the code

This line of code releases React composite events to reduce memory overhead. The core of the event handling entry in executeDispatchesInOrder:

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

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

参 考 η­” 摈 : THE dispatchListeners function is a callback to a Po model, and the dispatchin参 考 is the corresponding component of a Po model, passing these arguments to the executeDispatch:

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

The invokeGuardedCallback is quite simple:

function invokeGuardedCallback(name, func, a) {
    func(a);
}
Copy the code

参 考 η­” 摈 Func (a) is a listener(event) in the 参 考 η­” 摈, which is why 参 考 η­” 摈 our React event callback function can pick up native f models.

4. To summarize

React event system in order to compatible with all versions of the browser and done a lot of work, we don’t have to sit to study is how to implement these, unlike native event, only is to React to unified event rather than distributed storage and management, capture internal generated after synthetic events enhance browser compatibility degree, After the callback function is executed, the memory is destroyed to free up, thus greatly improving the response performance of web pages.

Review: React Source Code Parsing (1): Component implementation and Mounting “React Source Code Parsing (2): Component Types and Lifecycle” React Source Code Parsing (3): Understanding Transactions and Queues “contact email: [email protected]