React Incident Mechanism

Questions about React

  • 1. Why do you want to bind manuallythis
  • 2.ReactWhat is the difference between an event and a native event
  • 3.ReactCan I mix the execution sequence of events and native events?
  • 4.ReactHow to Resolve Cross-browser Compatibility by Event
  • 5. What is a composite event

The following is a flow chart summarizing all the execution processes after I read the source code. No code will be posted. If you want to read the code and see how it is implemented, you can look for it in the source code according to the flow chart.

Event registration

image

  • Component load/update.
  • vialastPropsnextPropsJudge whether to add or delete events and call event registration and uninstallation methods respectively.
  • callEventPluginHubTheenqueuePutListenerCarry out event storage
  • ObtaindocumentObject.
  • According to the event name (such asonClickonCaptureClick) to determine whether to bubble or capture.
  • Judging whether it exists or notaddEventListenerMethod, otherwise use theattachEvent(IE compatible).
  • todocumentRegister native event callback asdispatchEvent(Unified Incident Distribution Mechanism).

Event storage

image

  • EventPluginHubResponsible for managing React synthesis eventscallbackWhich willcallbackStored inlistenerBankIn addition, thePlugin.
  • EventPluginHubTheputListenerThe method is to add a listener to the storage container.
  • Gets the unique identification of the element that bound the eventkey.
  • willcallbackAccording to the event type, the unique identification of the elementkeyStored inlistenerBankChina.
  • listenerBankThe structure of is:listenerBank[registrationName][key].

For example:

{
 onClick:{
 nodeid1:()=>{...}
 nodeid2:()=>{...}
 },
 onChange:{
 nodeid3:()=>{...}
 nodeid4:()=>{...}
 }
 }

Event Trigger/Execution

image

The execution of events here took advantage ofReactThe batch processing mechanism of, in the previous article[React Depth] setState Execution MechanismIt has already been analyzed in, and there will be no more analysis here.

  • TriggerdocumentRegisters callbacks for native eventsdispatchEvent
  • Gets the element that triggered the deepest level of this event

For example, the following code: first gets thethis.child

<div onClick={this.parentClick} ref={ref => this.parent = ref}>
<div onClick={this.childClick} ref={ref => this.child = ref}>
test
</div>
</div>
  • Traversing all the parent elements of this element, processing each level of element in turn.
  • Construct composite events.
  • The composite events of each level are stored ineventQueueIn the event queue.
  • TraversaleventQueue.
  • viaisPropagationStoppedJud whether that current event execute a method for preventing bubbling.
  • If the bubble is stopped, stop the traversal, otherwise passexecuteDispatchPerforms a composite event.
  • Release the event that the processing is complete.

reactRewritten in his own composite eventstopPropagationThe method willisPropagationStoppedSet totrueAnd then judging whether to continue execution according to the traversal in the process of traversing each level of events. This is it.reactSelf-actualized bubble mechanism.

Composite event

image

  • callEventPluginHubTheextractEventsMethods.
  • Loop all types ofEventPlugin(Tools and Methods Used to Handle Different Events).
  • In eachEventPluginAccording to different event types, different event pools are returned in.
  • Take out the composite event from the event pool and create a new one if the event pool is empty.
  • According to elementnodeid(unique identificationkey) and event types fromlistenerBinkRemove callback function from
  • Returns a callback function with composite event parameters

Overall process

Connect the above four processes in series.

image

Why do you want to bind this manually

Through the analysis of the event triggering process,dispatchEventCalledinvokeGuardedCallbackMethods.

function invokeGuardedCallback(name, func, a) {
try {
func(a);
} catch (x) {
if (caughtError === null) {
caughtError = x;
}
}
}

It can be seen that the callback function is directly called and the called component is not specified, so it is directly obtained without manual binding.thisYesundefined.

Experimental ones can be used hereProperty initialization syntax, that is, to declare the arrow function directly on the component. Arrow functions do not create their ownthis, it will only inherit from one level above its own scope chainthis. So this is where we areReactWhat you get from the event is the component itself.

What is the difference from the original event

  • ReactEvents are named after humps, not all lowercase.
  • viaJSXYou pass a function as an event handler instead of a string.

For example,HTML

<button onclick="activateLasers()">
 Activate Lasers
 </button>

InReactThere is a slight difference between:

<button onClick={activateLasers}>
 Activate Lasers
 </button>

Another difference is that you cannot return in ReactfalseTo prevent default behavior. Must be explicitly calledpreventDefault.

From the above implementation mechanism, we can conclude that:ReactI have implemented a set of event mechanism, simulated the process of event bubbling and capture, adopted event proxy, batch update and other methods, and smoothed the compatibility of various browsers.

ReactExecution sequence of events and native events

componentDidMount() {
 this.parent.addEventListener('click', (e) => {
 console.log('dom parent');
 })
 this.child.addEventListener('click', (e) => {
 console.log('dom child');
 })
 document.addEventListener('click', (e) => {
 console.log('document');
 })
 }
 
 childClick = (e) => {
 console.log('react child');
 }
 
 parentClick = (e) => {
 console.log('react parent');
 }
 
 render() {
 return (
 <div onClick={this.parentClick} ref={ref => this.parent = ref}>
 <div onClick={this.childClick} ref={ref => this.child = ref}>
 test
 </div>
 </div>)
 }

Results of implementation:

image

From the above process we can understand:

  • reactAll events of are mounted on thedocumentIn
  • When the real dom triggers, it bubbles todocumentIt will not be right until later.reactEvent handling
  • Therefore, the original events will be executed first.
  • Then executereactComposite event
  • In the end, the execution is really indocumentEvents mounted on

Can react events be mixed with native events?

reactIt is best not to mix events with native events.

If executed in a native eventstopPropagationMethod will cause otherreactThe incident lapsed. Because events for all elements will not bubble todocumentGo.

It is not difficult to conclude from the above implementation mechanism that all react events will not be registered.

Composite events, browser compatibility

function handleClick(e) {
 e.preventDefault();
 console.log('The link was clicked.');
 }

Here,eIt is a composite event.ReactAccording toW3CThe specification defines this composite event, so you don’t need to worry about cross-browser compatibility.

The event handler will passSyntheticEventThis is a cross-browser native event wrapper. It has the same interface as browser native events, includingstopPropagation()AndpreventDefault()They work the same way in all browsers.

Each ..SyntheticEventObjects all have the following properties:

boolean bubbles
boolean cancelable
DOMEventTarget currentTarget
boolean defaultPrevented
number eventPhase
boolean isTrusted
DOMEvent nativeEvent
void preventDefault()
boolean isDefaultPrevented()
void stopPropagation()
boolean isPropagationStopped()
DOMEventTarget target
number timeStamp
string type

ReactSyntheticSyntheticEventThe event pool is adopted, which can greatly save memory without frequently creating and destroying event objects.

In addition, regardless of the browser environment, the browser will uniformly create the event type as a composite event, thus achieving the purpose of browser compatibility.

Recommended reading

[React Deeper] setState’s Execution Mechanism