Skip to content

Instantly share code, notes, and snippets.

@ggregoire
Created October 13, 2016 20:35
Show Gist options
  • Save ggregoire/ce7bc946212920c0a6bad8125567d001 to your computer and use it in GitHub Desktop.
Save ggregoire/ce7bc946212920c0a6bad8125567d001 to your computer and use it in GitHub Desktop.
React: stopPropagation VS nativeEvent.stopImmediatePropagation

TL;DR

If you mix JS event listeners and React event listeners, you need

event.nativeEvent.stopImmediatePropagation()

Scenario

We have a Modal including an input.

We would like to close our modal on pressing ESC.

We want to keep the expected bahavior for our input: when focused, be able to blur it on pressing ESC.

We need to stop the event propagation to blur the input without closing the modal.

With stopPropagation

class Modal extends Component {
  componentDidMount() {
    document.addEventListener('keydown', this.closeModal);
  }

  componentWillUnmount() {
    document.removeEventListener('keydown', this.closeModal);
  }
  
  closeModal = () => console.log('closeModal');
   
  handleKeyDown = (e) => e.stopPropagation();

  render() {
    return (
      <div className="modal">
        <input type="text" onKeyDown={this.handleKeyDown} />
      </div>
    );
  }
}

/**
*  Action: click the input then press ESC
*
*  Output: "closeModal"
*
*  => NOK
*/

With nativeEvent.stopImmediatePropagation

class Modal extends Component {
  componentDidMount() {
    document.addEventListener('keydown', this.closeModal);
  }

  componentWillUnmount() {
    document.removeEventListener('keydown', this.closeModal);
  }
  
  closeModal = () => console.log('closeModal');
   
  handleKeyDown = (e) => e.nativeEvent.stopImmediatePropagation();

  render() {
    return (
      <div className="modal">
        <input type="text" onKeyDown={this.handleKeyDown} />
      </div>
    );
  }
}

/**
*  Action: click the input then press ESC
*
*  Output:
*
*  => OK
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment