Vikram
Vikram

Reputation: 632

Reactjs: Event delegation similar to jQuery `on()`?

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.

Upvotes: 4

Views: 1493

Answers (2)

Nate Kimball
Nate Kimball

Reputation: 968

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.

Upvotes: 0

samAlvin
samAlvin

Reputation: 1678

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.

Upvotes: 1

Related Questions