Reputation: 18885
I need some help with understanding the so-called synthetic events in ReactJS. I wrote the following toy program that has a Video
component and a VideoList
component. When a video in the rendered list of videos is clicked, I would print out what video gets clicked in the console.
I don't understand how the event onVideoSelected() gets defined. Is it replaced by the onClick() event in the rendered Video
component?
Thanks!
var Video = React.createClass({
handleClick: function() {
this.props.onVideoSelected(this.props.title);
},
render: function() {
return <li><div onClick={this.handleClick} className="bg-success">{this.props.title}</div></li>;
}
});
var VideoList = React.createClass({
propTypes: {
data: React.PropTypes.array.isRequired
},
handleVideoSelected: function(title) {
console.log('selected Video title is: ' + title);
},
render: function() {
return (
<div className="panel panel-default"><div className="panel-heading">List of Videos</div><ul>
{data.map(function (v) {
return <Video onVideoSelected={this.handleVideoSelected} key={v.title} title={v.title} />;
},this)}
</ul></div>
);
}
});
var data = [
{title: 'video title 1', link: 'http://www.youtube.com/1'},
{title: 'video title 2', link: 'http://www.youtube.com/2'},
{title: 'video title 3', link: 'http://www.youtube.com/3'}
];
React.render(<VideoList data={data} />, document.getElementById('videolist'));
Upvotes: 6
Views: 7823
Reputation: 159125
There's actually no magic going on here, just passing functions around. onVideoSelected
is a function reference that you passed into the Video
component via a property; said another way, the flow goes like this:
this.handleClick
.handleClick
? Call this.props.onVideoSelected
.onVideoSelected
defined? It got passed into the component, just like any other property.onVideoSelected
property? A reference to the VideoList
's handleVideoSelected
function.It may help to compare it to some sorta-similar, simplified jQuery code:
function handleVideoSelected(title) {
console.log('selected Video title is: ' + title);
}
function createVideoDiv(onVideoSelected, title) {
var div = $("<div className="bg-success"></div>").text(title).appendTo(...);
div.on("click", function() {
// call the function that was passed to us
onVideoSelected(title);
});
}
$.each(videos, function(idx, video) {
createVideoDiv(handleVideoSelected, video.title);
});
In the jQuery version, you pass handleVideoSelected
into createVideoDiv
; similarly, in the React version, you pass handleVideoSelected
into Video
via props.
Upvotes: 7
Reputation: 44900
After your onClick
handler is called in the Video
component you are no longer dealing with events; these are plain old function calls.
To keep a reference to the video title, pass a curried version of handleVideoSelected
with the title as the first arg by using Function.prototype.bind:
{this.props.data.map(function (v) {
return <Video onVideoSelected={this.handleVideoSelected.bind(this, v.title)} key={v.title} title={v.title} />;
}, this)}
(I also prepended this.props
to data
. Looks like a typo in your code.)
This is how individual Todos are identified in the "Expose Component Functions" doc.
Upvotes: 1