1

Can anyone tell me why handleChange isn't triggered when I click any of the checkboxes? The checkboxes is rendered as I want with the expected value, but the click handler is not triggered.

 37   var AutocompleteFromCheckboxes = React.createClass({
 38     handleChange: function(e) {
 39       console.log('hi');
 40       return 1;
 41     },
 42     render: function() {
 43       var autocompleteFrom = this.props.autocomplete_from.map(function(value) {
 44         return (
 45           <label for={value}>
 46             <input type="checkbox" name={value} value="{value}"
 47               onChange={this.handleChange}
 48               ref="autocomplete-from"/>
 49             {value}
 50           </label>
 51         );
 52       });
 53       return (
 54         <div className="autocomplete-from">
 55           {autocompleteFrom}
 56         </div>
 57       );
 58     }
 59   });
martins
  • 7,647
  • 6
  • 41
  • 67

1 Answers1

1

In your code the anonymous function runs with the wrong context: as soon as you don't set it explicitly it's being set to undefined.

It means that this is undefined hence this.handleChange should throw an exception (not sure why you haven't checked the console for that. And if you had - why you didn't mention it).

To solve the problem you may pass the context explicitly as the second argument for the Array.prototype.map function call:

var autocompleteFrom = this.props.autocomplete_from.map(function(value) {
    // ...
}, this);

And as soon as you solve this particular issue and ready to dive into the details on how this works in JS, please follow this amazing answer.

Community
  • 1
  • 1
zerkms
  • 230,357
  • 57
  • 408
  • 498
  • 1
    In addition to @zerkms answer, this is a good reason to use strict mode - if you'd had `'use strict';` at the top of the module containing this component, you'd have got a `this is undefined` error pointing to the `this.handleChange` line. – Jonny Buchanan Apr 07 '15 at 09:19
  • Or a good reason to use ES6 with arrow functions, and never worry about `this` scoping again \*brushes es5 off hands\*. Really though, it's just a compiler flag on jstransform (jsx/reactify/jsx-loader), go ahead and flip it. – Brigand Apr 07 '15 at 09:29
  • Without `'use strict';`, `this` will be `window`, not undefined. – Alex McMillan Apr 07 '15 at 09:38
  • @AlexMcMillan yep, but then `this.handleChange` will be undefined. Not much difference (if you know how to use debugger). – zerkms Apr 07 '15 at 09:40
  • @zerkms big difference... `object.undefinedProperty` will pass `undefined`, making it a silent error - hard to find without going through the code and determining if `object` is what you expected it to be. `undefined.property` will throw an error, immediately alerting you to the problem. – Alex McMillan Apr 07 '15 at 09:43
  • @AlexMcMillan it will not be silent - it will be an exception on invocation. With debugger it's obvious instantly - just go up 1-2 levels on the stack. – zerkms Apr 07 '15 at 09:44
  • @zerkms aah... no. It *may* produce an exception further down the line, where you're trying to access the returned object and find that it is `undefined`.. but that line itself will *not* produce an exception. – Alex McMillan Apr 07 '15 at 09:45
  • @AlexMcMillan oh, react silently ignores if the argument is not a valid callable. My apologies then. It surprised me - since that's what I would expect to see (but never experienced since I never tried to pass non existing handler there) – zerkms Apr 07 '15 at 09:46
  • Thanks guys! :-) Adding `this` as the second argument fixed it. Thanks for the link to more info on `this`, I'll read up on it right away. Also noticed that `'use strict';` would have given me a nice hint **Uncaught TypeError: Cannot read property 'handleChange' of undefined**. – martins Apr 07 '15 at 10:39