4

I am new to React.js. I created a list Component where items get added/removed frequently. Each item should have a click and/or hover events.

I would like to do event delegation in similar way we do in jQuery using on(event, selector, data, handler) method so that I can bind/unbind event on the list parent element without worrying about event bindning/unbinding for each child item on add/remove.

Vikram
  • 622
  • 1
  • 6
  • 18
  • I believe React automatically delegates events (e.g., if you put an `onClick` on each item, React doesn't actually do that), but I can't (any longer) find that in the React documentation... – T.J. Crowder Mar 07 '17 at 09:03
  • @T.J.Crowder I believe what you are refering to is known as synthetic event handlers. https://facebook.github.io/react/docs/events.html – spirift Mar 07 '17 at 09:12
  • @spirift: That's part of it (but they're for cross-browser normalization as well, like jQuery's `$.Event`), but the docs used to specifically call out that handlers were delegated. But searches for [delegation](https://www.google.com/search?q=%22delegation%22+site:https:%2F%2Ffacebook.github.io%2Freact%2Fdocs%2F&*) or [delegate](https://www.google.com/search?q=%22delegate%22+site:https:%2F%2Ffacebook.github.io%2Freact%2Fdocs%2F&*) in the docs no longer turn up results. – T.J. Crowder Mar 07 '17 at 09:21
  • @T.J.Crowder I think you were right, ` – Littlee Nov 15 '18 at 16:15

2 Answers2

1

As the documentation says,

Handling events with React elements is very similar to handling events on DOM elements. React events are named using camelCase, rather than lowercase. With JSX you pass a function as the event handler, rather than a string. (https://facebook.github.io/react/docs/handling-events.html)

Assuming you use a class as the React component, if you want each item to have click and/or hover event you can just type these inside render() method of your class:

<a onClick={this.onClickEventHandler}
   onMouseEnter={this.onMouseEnterEventHandler}
   onMouseLeave={this.onMouseLeaveEventHandler}>
sample item
</a>

After that you can declare those event handlers (onClickEventHandler, onMouseEnterEventHandler, and onMouseLeaveEventHandler) in your class and tell them what to do.

Lastly You need to bind the event handlers in your class constructor:

constructor(props){
  super(props);
  this.onClickEventHandler = this.onClickEventHandler.bind(this);
  this.onMouseEnterEventHandler= this.onMouseEnterEventHandler.bind(this);
  this.onMouseLeaveEventHandler= this.onMouseLeaveEventHandler.bind(this);
}

See this Plunker for the example of event handling in React.

You can later use these event in the parent component by implementing the concept of "lifting state up". That way you can run a method in the parent component by triggering event in the child component. See this Plunker for the example of lifting state up in React.

samAlvin
  • 1,648
  • 1
  • 11
  • 35
0

In React, rather than using selectors to bind/unbind events, we usually add synthetic event handlers directly to the children. In a component like a list, whenever the list items are updated (added/removed/edited, etc...), the parent is rerendered. So, in your render function, you might do something like this:

render(){

  // your list component will either keep the items in its state, 
  // or receive them as props from its parent or from a store like redux.

  const { listItems } = this.props;
  
  // then, adding your event handlers is simply a matter of mapping over 
  // your list items and rendering your desired jsx from each item:

  const renderedItems = () => {
    return listItems.map(item => {
      return (
        <div 
          onClick={ this.handleClick(item) }
          onMouseEnter={ this.handleMouseEnter(item) }>
          { item.text }
        </div> 
      );
    });
  };
  
  // then it's just a matter of calling your rendered items 
  // in render's return:
  
  return(
    <div>
      { renderedItems() }
    </div>
  )
}

Note that no binding is necessary in components that use React's createClass() function, since React automatically handles binding.

Nate Kimball
  • 928
  • 8
  • 22
  • Suppose I have a generic item component that can be **re-used** as child in different list components where same item component may have different behavior (for user interactions: click or other events) for each parent component. In this scenario, Synthetic event handler will not work. – Vikram Mar 07 '17 at 11:03
  • In your example, I guess `this.handleClick(item)` and `this.handleMouseEnter(item)` will execute the methods instead of bind them. – Vikram Mar 07 '17 at 11:04
  • 1
    @Vikram - in that scenario, you could have the list component pass its handler to the child. – Nate Kimball Mar 07 '17 at 11:28