[reactjs] React prevent event bubbling in nested components on click

On the order of DOM events: CAPTURING vs BUBBLING

There are two stages for how events propagate. These are called "capturing" and "bubbling".

               | |                                   / \
---------------| |-----------------   ---------------| |-----------------
| element1     | |                |   | element1     | |                |
|   -----------| |-----------     |   |   -----------| |-----------     |
|   |element2  \ /          |     |   |   |element2  | |          |     |
|   -------------------------     |   |   -------------------------     |
|        Event CAPTURING          |   |        Event BUBBLING           |
-----------------------------------   -----------------------------------

The capturing stage happen first, and are then followed by the bubbling stage. When you register an event using the regular DOM api, the events will be part of the bubbling stage by default, but this can be specified upon event creation

// CAPTURING event
button.addEventListener('click', handleClick, true)

// BUBBLING events
button.addEventListener('click', handleClick, false)
button.addEventListener('click', handleClick)

In React, bubbling events are also what you use by default.

// handleClick is a BUBBLING (synthetic) event
<button onClick={handleClick}></button>

// handleClick is a CAPTURING (synthetic) event
<button onClickCapture={handleClick}></button>

Let's take a look inside our handleClick callback (React):

function handleClick(e) {
  // This will prevent any synthetic events from firing after this one
  e.stopPropagation()
}
function handleClick(e) {
  // This will set e.defaultPrevented to true
  // (for all synthetic events firing after this one)
  e.preventDefault()  
}

An alternative that I haven't seen mentioned here

If you call e.preventDefault() in all of your events, you can check if an event has already been handled, and prevent it from being handled again:

handleEvent(e) {
  if (e.defaultPrevented) return  // Exits here if event has been handled
  e.preventDefault()

  // Perform whatever you need to here.
}

For the difference between synthetic events and native events, see the React documentation: https://reactjs.org/docs/events.html

Examples related to reactjs

Error: Node Sass version 5.0.0 is incompatible with ^4.0.0 TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined raised when starting react app Template not provided using create-react-app How to resolve the error on 'react-native start' Element implicitly has an 'any' type because expression of type 'string' can't be used to index Invalid hook call. Hooks can only be called inside of the body of a function component How to style components using makeStyles and still have lifecycle methods in Material UI? React Hook "useState" is called in function "app" which is neither a React function component or a custom React Hook function How to fix missing dependency warning when using useEffect React Hook? Unable to load script.Make sure you are either running a Metro server or that your bundle 'index.android.bundle' is packaged correctly for release

Examples related to onclick

How to use onClick with divs in React.js React prevent event bubbling in nested components on click React onClick function fires on render Run php function on button click Passing string parameter in JavaScript function Simple if else onclick then do? How to call a php script/function on a html button click Change Button color onClick RecyclerView onClick javascript get x and y coordinates on mouse click

Examples related to event-propagation

React prevent event bubbling in nested components on click Stop mouse event propagation Prevent scrolling of parent element when inner element scroll position reaches top/bottom? How do I prevent a parent's onclick event from firing when a child anchor is clicked? event.preventDefault() vs. return false