Welcome to visit personal blog website: www.zhuxin.club

1. Native events

Native is js native events, such as through the document. The addEventListener to set up to monitor events.

React has its own event mechanism (see Compositing events below), but there are some business scenarios where we still need to use native events. For example, if we package a Modal popover component, we need to close the popover when clicking on a non-popover area. At this time, we can only perform native click event listening for Document.

Since native events need to be bound to the real DOM, they are usually bound during the componentDidMount phase or during the function execution of the component/element ref, and be careful to unbind during the componentWillUnmount phase to avoid memory leaks.

2. Composite events

React has its own event mechanism that reencapsulates most of the native events. Synthetic events use event pooling, which saves a lot of memory without constantly creating and destroying event objects.

In React, if we need to bind events, we often write this in JSX:

handleClick(){
}
<div onClick={this.handleClick.bind(this}> React </div>Copy the code

General principle:

Instead of tying the click event to the actual DOM of that div, React listens for all supported events at document. When the event happens and bubbles up to document, React wraps the event content and hands it off to the actual handler.

As an example, the entire event life cycle is shown as follows:

Summary of some characteristics of composite events:

  • Events registered on React end up being bound to the Document DOM, not the DOM of the React component.
  • React traces back from the triggered component to the parent component in the form of a queue and then invokes their CALLBACK defined in JSX
  • React manages the creation and destruction of synthesized event objects in the form of object pools, reducing garbage generation and allocating memory for new objects, improving performance

React synthesizes events

Why does the React event need to manually bind this

React starts from the component instance triggered by the event, walks through the virtual DOM tree, pulls the events we bind from the tree, collects them, and executes. Here’s an example:

class Test extends React.Component {
   fatherHandler =  function father() { / *... * /}
   childHander = function child() {/ *... * /}

   render(){
     return (
       <div onClick={this.fatherHandler}>
         <span onClick={this.childHander}>
         </span>
       </div>); }}Copy the code

React puts the above event handlers in an array when the event is triggered

[father, child]
Copy the code

Finally, React executes all event handlers that need to be executed by simply iterating through the array. React temporarily saves the function, so if it’s executed, this will be lost.

If you save React and save the instance, you can still do it. You don’t need to bind this, but it’s too expensive for React.

3. Triggering sequence of native and synthetic 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>)}Copy the code

After clicking Test in Child, the events are triggered in the following order:

Conclusion:

Regardless of whether it is the same type of event listening for the same element, native events are always fired before synthetic events. This is due to the fact that all of the compositing events we talked about above end up being bound to the Documnet DOM, and when the compositing event is listening, it always bubbles up to the Document before it actually fires. Native events that are listened on documnet DOM are always fired last

4. Mix composite events with native events

React composite events and native events should not be mixed.

If stopPropagation is implemented in a native event, other react synthesized events of the same type will be invalidated. This is because all of the composition events and native events of sibling and descendant elements will not be able to bubble to the Document.

If only the e.topPropagation method is used in the composite event, the bubblings of the native event will not be affected

Related questions:

We know that the React event listener gets input parameters that are not browser native events. Native events can be obtained through e.ativeEvent. In this way, can synthetic events affect native events?

e.nativeEvent.stopPropagation

Even though the react composite event calls the native event’s bubbling-prevention function, it actually prevents bubbling-prevention in the outermost layer of the DOM, which is not as expected. That is, it ultimately only controls that the synthesized event currently listening for does not bubble up into the native event of the Document DOM

e.nativeEvent.stopImmediatePropagation

The method and the above nativeEvent. StopPropagation have similar function, can prevent the synthesis of the current monitoring event bubbling to document DOM native events

StopImmediatePropagation is often used to prevent unnecessary execution in multiple event listeners when multiple third-party libraries are mixed. For example, if multiple listener functions are set for the same event on the same element, this method can control the listener function to fire only the first one

Both stopImmediatePropagation and stopPropagation text are original events. However, in React’s own event system, the latter was re-encapsulated but the former was not. Cause only call nativeEvent manually. In the event of synthetic stopImmediatePropagation.

In the React composite event mechanism, a component can only be bound to one event listener of the same type (when repeated definitions are made, subsequent listeners will overwrite the previous ones). Therefore, the composite event does not need to encapsulate stopImmediatePropagation.

So, in the synthesis of the React incident, e.n ativeEvent. StopPropagation and e.n ativeEvent. StopImmediatePropagation actual role are equivalent

In addition, due to the sequence of event binding, note that if the Document native event is bound before the react-dom.js loading, stopImmediatePropagation cannot be blocked.