How to set event handler in React sub-component

components, handler, onclick, reactjs

Solution

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>;
})

Problem

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).

Original source