Questions about React

  • 1. Why bind this manually

  • 2. What is the difference between React events and native events

  • 3. Can React events and native events be executed in the same order

  • 4. How do React events address cross-browser compatibility

  • 5. What are composite events

After I read the source code, the following is a summary of all the execution process of the flow chart, not the code, if you want to read the code to see how to achieve the specific, you can go to the source code according to the flow chart.

Event registration

  • Component load/update.
  • throughlastProps,nextPropsDetermine whether to call event registration and unload methods respectively to add and delete events.
  • callEventPluginHubtheenqueuePutListenerStore events
  • To obtaindocumentObject.
  • Based on the event name (e.gonClick,onCaptureClick) determine whether to bubble or capture.
  • Determine whether there isaddEventListenerMethod, otherwise usedattachEvent(Compatible with IE).
  • todocumentRegister the native event callback asdispatchEvent(Unified event distribution mechanism).

The event store

  • EventPluginHubResponsible for managing React synthesis eventscallback, it willcallbackStored in thelistenerBankIn addition, a class responsible for composing events is storedPlugin.
  • EventPluginHubtheputListenerYou do this by adding a listener to the storage container.
  • Gets the unique identity of the element to which the event is boundkey.
  • willcallbackThe unique identification of the element based on the event typekeyStored in thelistenerBankIn the.
  • listenerBankThe structure of:listenerBank[registrationName][key].

Such as:

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

Event firing/execution

React uses the React batching mechanism to execute events. The React in depth setState mechanism is described in the previous article.

  • The triggerdocumentRegister callbacks for native eventsdispatchEvent
  • Gets the element that triggers the deepest level of the event

For example, the following code: this.child is retrieved

      <div onClick={this.parentClick} ref={ref => this.parent = ref}>
        <div onClick={this.childClick} ref={ref => this.child = ref}>
          test
        </div>
      </div>
Copy the code
  • Iterate through all the parent elements of this element, processing each element in turn.
  • Construct a composite event.
  • Stores composite events at each level ineventQueueIn the event queue.
  • traverseeventQueue.
  • throughisPropagationStoppedDetermines whether the current event executes a bubbling prevention method.
  • If it stops bubbling, stop traversing, otherwise passexecuteDispatchExecute the composite event.
  • Release the event that has been processed.

React overrides the stopPropagation method in its own composite event, set isPropagationStopped to true, and then determines whether to proceed with each level of events based on that loop. This is the bubble mechanism react implements itself.

Synthetic events

  • callEventPluginHubtheextractEventsMethods.
  • Loop through all typesEventPluginTool methods for handling different events.
  • At the end of eachEventPluginReturns different event pools according to different event types.
  • Take the synthesized event from the event pool, and if the event pool is empty, create a new one.
  • According to the elementnodeid(Unique identifierkey) and the event type fromlistenerBinkRetrieves the callback function from
  • Returns a callback function with synthesized event parameters

The total process

Connect the four processes above in series.

Why bind this manually

DispatchEvent invokes the invokeGuardedCallback method through the analysis of the event triggering process.

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

The callback function is called directly without specifying the component to call, so this is undefined without manual binding.

Here you can use the experimental property initialization syntax, which is to declare the arrow function directly on the component. The arrow function does not create its own this; it only inherits this from the upper level of its scope chain. So what we get in the React event is the component itself.

How is it different from native events

  • React events are named with a hump instead of all lowercase.

  • With JSX, you pass a function as an event handler, not a string.

For example, HTML:

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

React is slightly different:

<button onClick={activateLasers}>
  Activate Lasers
</button>
Copy the code

Another difference is that in React you can’t prevent default behavior by returning false. PreventDefault must be explicitly called.

React implements an event mechanism, simulates event bubbling and capturing, uses event proxies, batch updates and other methods, and smooths out compatibility issues among browsers.

ReactThe execution order 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>)
  }
Copy the code

Execution Result:

We can understand from the above process:

  • reactAll events are mounted indocumentIn the
  • Bubbles to when the real DOM is triggereddocumentLater onreactEvent Processing
  • So native events are executed first
  • Then performreactSynthetic events
  • Finally the execution is really indocumentMount events on

Can react events and native events be mixed?

React events and native events should not be mixed.

If the stopPropagation method is executed in the native event, other React events will become invalid. Because all the elements’ events will not bubble up to the document.

React events will not be registered.

Synthetic event, browser compatible

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

Here, e is a composite event. React defines this composite event according to the W3C specification, so you don’t need to worry about cross-browser compatibility.

The event handler passes an instance of SyntheticEvent, which is a cross-browser native event wrapper. It has the same interface as browser native events, including stopPropagation() and preventDefault(), and they work the same in all browsers.

Each SyntheticEvent object has 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
Copy the code

The React synthesized SyntheticEvents use event pooling, which saves a lot of memory without constantly creating and destroying event objects.

In addition, browsers create this event type as a composite event regardless of browser environment, thus achieving browser compatibility.

Recommended reading

  • 【React in-Depth 】setState execution mechanism

  • A function that tells you ‘Why 0.1+0.2! = 0.3 ‘