Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set event handler in React sub-component

Tags:

I'm having trouble getting menu items connected to an event handler. Here's a mock of the UI showing state changes over time. It's a dropdown menu (via Bootstrap), with the root menu item showing the current selection:

[ANN]<click  ...  [ANN]             ...    [BOB]<click  ...  [BOB]                       [Ann]                                      [Ann]                     [Bob]<click + ajax                         [Bob]                     [Cal]                                      [Cal] 

The end goal is to change the page content asynchronously based on the user's selection. Clicking on Bob should trigger the handleClick, but it's not.

As a side note, I'm not terribly happy with the way componentDidMount calls this.handleClick();, but it works for now as a way to get initial menu content from the server.

/** @jsx React.DOM */  var CurrentSelection = React.createClass({   componentDidMount: function() {     this.handleClick();   },    handleClick: function(event) {     alert('clicked');     // Ajax details ommitted since we never get here via onClick   },   getInitialState: function() {     return {title: "Loading items...", items: []};   },   render: function() {     var itemNodes = this.state.items.map(function (item) {       return <li key={item}><a href='#' onClick={this.handleClick}>{item}</a></li>;     });      return <ul className='nav'>       <li className='dropdown'>         <a href='#' className='dropdown-toggle' data-toggle='dropdown'>{this.state.title}</a>         <ul className='dropdown-menu'>{itemNodes}</ul>       </li>     </ul>;   } });   $(document).ready(function() {   React.renderComponent(     CurrentSelection(),     document.getElementById('item-selection')   ); }); 

I'm almost positive that my hazy understanding of javascript scoping is to blame, but everything I've tried so far has failed (including trying to pass the handler down through props).

like image 799
clozach Avatar asked Jan 09 '14 02:01

clozach


People also ask

How do you pass an event handler to a component?

Passing Event Handler to Subcomponent The Address component is using the destructuring assignment { type, houseNo, clickHandler } to access the passed prop values directly. The clickHandler is a function to handle clicks, which is being passed to the onClick attribute.

Can we use same event handler on multiple components?

Absolutely yes! You can fire a lightning event and that will be handled in each & every component which has a handler defined in it.

Can I add event listener to React component?

To use the addEventListener method in function components in React: Set the ref prop on the element. Use the current property on the ref to get access to the element. Add the event listener in the useEffect hook.

How can we pass an event handler to the child component?

To pass an onChange event handler to a child component in React: Define the event handler function in the parent component. Pass it as a prop to the child component, e.g. <Child handleChange={handleChange} /> . Set it to the onChange prop on the input field in the child.


1 Answers

The problem is that you're creating the item nodes using an anonymous function, and inside that this means the window. The fix is to add .bind(this) to the anonymous function.

var itemNodes = this.state.items.map(function (item) {   return <li key={item}><a href='#' onClick={this.handleClick}>{item}</a></li>; }.bind(this)); 

Or create a copy of this and use that instead:

var _this = this, itemNodes = this.state.items.map(function (item) {   return <li key={item}><a href='#' onClick={_this.handleClick}>{item}</a></li>; }) 
like image 110
tungd Avatar answered Sep 30 '22 13:09

tungd