Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: event bubbling through nested components

Let's say I have nested components like this:

<root />   <comp1 />     <comp2 />       <target id={this.props.id}>         <div>click me</div> 

I want to make clicking on target run a function on root:

//on root component this.action = function(id){} 

Do I need to do manually set a property on every component in the chain, like in the React tutorial example? Jsfiddle

<root />   <comp1 clickHandler={this.action}/>     <comp2 clickHandler={this.clickHandler}/>       <target id={this.props.id} clickHandler={this.clickHandler} />         <div onClick={this.props.clickHandler.bind(this, this.props.id)}>click me</div> 

Or is there some way to bubble the events up like in normal DOM?

like image 437
kapsi Avatar asked Sep 14 '15 08:09

kapsi


People also ask

How do you do event bubbling in React?

Event bubbling in React refers to when the innermost component handles an event, and events bubble outwards. In React, the innermost element will first be able to handle the event, and then surrounding elements will then be able to handle it themselves.

Which methods will prevent event bubbling?

stopPropagation() method stops the bubbling of an event to parent elements, preventing any parent event handlers from being executed.

How would you prevent an event bubbling in a software application?

Stop Event Bubbling : If you want to stop the event bubbling, this can be achieved by the use of the event. stopPropagation() method. If you want to stop the event flow from event target to top element in DOM, event. stopPropagation() method stops the event to travel to the bottom to top.


1 Answers

React supports Synthetic Events across it's Virtual DOM in both capturing and bubbling phases (as described here: https://facebook.github.io/react/docs/events.html).

This means that you could put an onClick handler on any DOM element near the root and it should trigger for all Click events on the page:

<root>   <div onClick={this.handleAllClickEvents}>     <comp1>       <comp2>         <target>           <div id={this.props.id}>click me</div> 

However, since it will fire for all click events, you would need to disambiguate between them in the click handler (which makes for some pretty ugly code).

function handleAllClickEvents(event) {   var target = event.relatedTarget;   var targetId = target.id;   switch(targetId) {     case 'myBtn1':       // handle myBtn1 click event     case 'myBtn2':       // handle myBtn2 click event   } } 

This style of Event Delegation is actually what React does under the hood (https://shripadk.github.io/react/docs/interactivity-and-dynamic-uis.html#under-the-hood-autobinding-and-event-delegation) so you have to ask yourself if that's what you really want to do.

Alternatively you might want to look at something like the Dispatcher pattern in Flux (https://reactjs.org/blog/2014/07/30/flux-actions-and-the-dispatcher.html). It's a little bit more complicated to get going but it's a better solution overall.

like image 172
chrismilleruk Avatar answered Oct 09 '22 02:10

chrismilleruk