Prevent event bubbling in react

Keywords: React

Look directly at the chestnuts:

Three div s on the page, as shown in the figure
1. When the native event registration is not involved and only react event is involved, e.stopPropagation() is used to prevent bubbling. The code is as follows:

import React, { Component } from 'react';
import './App.css';

class App extends Component {

  handleClickTestBox = (e) => {
    console.warn('handleClickTestBox: ', e);
  }

  handleClickTestBox2 = (e) => {
    console.warn('handleClickTestBox2: ', e);
  }

  handleClickTestBox3 = (e) => {
    e.stopPropagation();
    console.warn('handleClickTestBox3: ', e);
  }

  render() {
    return (
      <div
        className="test-box"
        onClick={this.handleClickTestBox}
      >
        <div
          onClick={this.handleClickTestBox2}
        >
          <div
            onClick={this.handleClickTestBox3}
          >
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Console printing:

Successfully prevent bubbling of events

2. After registering the native event with document.addEventListener, e.stopPropagation() cannot prevent the bubbling between the document and e.nativeEvent.stopImmediatePropagation() method. The code is as follows:

import React, { Component } from 'react';
import './App.css';

class App extends Component {

  componentDidMount() {
    document.addEventListener('click', this.handleDocumentClick, false);
  }

  handleDocumentClick = (e) => {
    console.log('handleDocumentClick: ', e);
  }

  handleClickTestBox = (e) => {
    console.warn('handleClickTestBox: ', e);
  }

  handleClickTestBox2 = (e) => {
    console.warn('handleClickTestBox2: ', e);
  }

  handleClickTestBox3 = (e) => {
    // Prevent bubbling of synthetic events
    e.stopPropagation();
    // Stopping and bubbling of native events
    e.nativeEvent.stopImmediatePropagation();
    console.warn('handleClickTestBox3: ', e);
  }

  render() {
    return (
      <div
        className="test-box"
        onClick={this.handleClickTestBox}
      >
        <div
          onClick={this.handleClickTestBox2}
        >
          <div
            onClick={this.handleClickTestBox3}
          >
          </div>
        </div>
      </div>
    );
  }
}

export default App;

3. To prevent bubbles between synthetic events and non synthetic events (except document), the above two methods are not applicable. e.target judgment is needed. The code is as follows:

import React, { Component } from 'react';
import './App.css';

class App extends Component {

  componentDidMount() {
    document.addEventListener('click', this.handleDocumentClick, false);
    document.body.addEventListener('click', this.handleBodyClick, false);
  }

  handleDocumentClick = (e) => {
    console.log('handleDocumentClick: ', e);
  }

  handleBodyClick = (e) => {
    if (e.target && e.target === document.querySelector('#inner')) {
      return;
    }
    console.log('handleBodyClick: ', e);
  }

  handleClickTestBox = (e) => {
    console.warn('handleClickTestBox: ', e);
  }

  handleClickTestBox2 = (e) => {
    console.warn('handleClickTestBox2: ', e);
  }

  handleClickTestBox3 = (e) => {
    // Prevent bubbling of synthetic events
    e.stopPropagation();
    // Stopping and bubbling of native events
    e.nativeEvent.stopImmediatePropagation();
    console.warn('handleClickTestBox3: ', e);
  }

  render() {
    return (
      <div
        className="test-box"
        onClick={this.handleClickTestBox}
      >
        <div
          onClick={this.handleClickTestBox2}
        >
          <div
            id="inner"
            onClick={this.handleClickTestBox3}
          >
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Console printing:

Posted by robos99 on Thu, 02 Jan 2020 14:25:43 -0800