Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding synthetic events in ReactJS

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'));
like image 439
TonyGW Avatar asked Jan 12 '15 02:01

TonyGW


2 Answers

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:

  • What happens when you click the div? Call this.handleClick.
  • What happens when you call handleClick? Call this.props.onVideoSelected.
  • How is onVideoSelected defined? It got passed into the component, just like any other property.
  • What was passed in to the 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.

like image 97
Michelle Tilley Avatar answered Sep 19 '22 01:09

Michelle Tilley


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.

like image 37
Ross Allen Avatar answered Sep 19 '22 01:09

Ross Allen