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'));
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.
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.
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