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?
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.
stopPropagation() method stops the bubbling of an event to parent elements, preventing any parent event handlers from being executed.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With