0

We're creating a new site and we chose reactjs to do this. And right now I'm researching on events in Javascript and luckily I stumbled on this site where he teaches how to handle events for many elements and letting the parent handle the event and basically is what we are doing for out site as well right now.

As I continued to research, I also stumbled upon this answer here (more react oriented) where it says I would pass the function/method from the parent to the child.

Is it promoting the same way as what was mentioned on the first link? Also, is this the way to do this (like the first link to handle events) in reactjs? Should I implement somewhere along this lines?

Follow up question... or should I ask this separately?

If I have

<Parent>
  <ChildComponent>
  <ChildComponent>
  ...

and a child when clicked I add a class to it, say .selected. But I'd need to remove it to the others since they are not selected anymore. In jQuery I could've done something like

$('.child-components').removeClass('selected');
$(this).addClass('selected');

How to do this the react way?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
index
  • 3,697
  • 7
  • 36
  • 55

2 Answers2

0

For your first question, it would depend on the exact situation and the relationship between the parent and child component.

For example, handling a click event for one child component (out of many similar others under the same parent) would be better done by the parent.

But as a counterexample, consider a component that's a text input. It might perform its own validation before passing it to the parent (which could be the form that handles submission), in which case handling the change events would be better done within the component itself rather than by the parent.

In general, yes, the React way to handle events is to pass the event handler functions from parent to child as necessary.

For your second question, you just need to store the index (or some other ID) of the selected child component in the parent's state. Then, in the parent's render method (where I assume the child components are also rendered), use that information to add the .selected class to the proper child component. So the parent knows which child is selected, and takes care of rendering them properly.

The other way around, you can then update the parent's state based on child events (e.g., setting selection when a child is clicked) by using a click handler function passed from the parent to the child via props.

Hope this helps!

Jomel Imperio
  • 924
  • 4
  • 16
  • Hrmn. Actually I was trying out the one where the parent handles all of it then I was stumped because I just noticed we needed to have other specific things to do when they are a different type of `ChildComponent`. But should I already separate them or should I just bombard the parent with `if`conditions? I'm not sure w/c is more performant as this is my first creating a heavy JS site. How do I keep tabs of the selected? Is there a way in reactjs that keeps tabs of their ID's? Or do I just assign them? Also, if I do pass a function, maybe I could interpolate that one plus the first question. – index May 12 '15 at 06:23
0

The article you mentioned is using event bubbling. It attaches one event handler, and lets all events bubble up to it. It's a very good approach, and it's actually what React does internally. It only seems like you attach event handlers directly to an element when you do <div onClick={this.handleClick} /> but what React does is to only set up one click listener for the top node. It only calls your this.handleClick if that event bubbled up to that element.

For your second question, you would do something like this:

var Child = React.createClass({
  render: function () {
    return <li className={this.props.className} onClick={this.props.onClick}>{this.props.text}</li>;
  }
});

var Parent = React.createClass({
  getInitialState: function () {
    var items = [
      {text: 'One'},
      {text: 'Two'},
      {text: 'Three'}
    ];
    var selected = items[0];

    return {
      items: items,
      selected: selected
    };
  },
  handleClick: function (item) {
    this.setState({selected: item});
  },
  render: function () {
    var self = this;

    return (
      <ul>
        {this.state.items.map(function (item) {
          return (
            <Child 
              key={item.text}
              className={this.state.selected === item ? 'selected' : ''}
              onClick={self.handleClick.bind(self, item)}
              text={item.text}
            />
          );
        })}
      </ul>
    );
  }
});

Here's a working JSBin: http://jsbin.com/libunecaba/1/edit?js,output

Anders Ekdahl
  • 22,685
  • 4
  • 70
  • 59