React: Keyboard Event Handlers All 'Null'

JavascriptReactjsReact Jsx

Javascript Problem Overview


I'm unable to get any of the React SyntheticKeyboardEvent handlers to register anything except null for the event properties.

I've isolated the component in a fiddle and am getting the same result as in my application. Can anyone see what I'm doing wrong?

http://jsfiddle.net/kb3gN/1405/

var Hello = React.createClass({
    render: function() {
      return (
      <div>
        <p contentEditable="true"
           onKeyDown={this.handleKeyDown}
           onKeyUp={this.handleKeyUp}
           onKeyPress={this.handleKeyPress}>Foobar</p>
        <textarea
           onKeyDown={this.handleKeyDown}
           onKeyUp={this.handleKeyUp}
           onKeyPress={this.handleKeyPress}>
        </textarea>
        <div>
          <input type="text" name="foo" 
           onKeyDown={this.handleKeyDown}
           onKeyUp={this.handleKeyUp}
           onKeyPress={this.handleKeyPress} />
        </div>
      </div>
      );
    },
    
    handleKeyDown: function(e) {
      console.log(e);
    },
    
    handleKeyUp: function(e) {
     console.log(e);
    },
    
    handleKeyPress: function(e) {
     console.log(e); 
    }
});
 
React.renderComponent(<Hello />, document.body);

Javascript Solutions


Solution 1 - Javascript

BinaryMuse provided the answer on IRC. Turns out it's just a quirk; you can't read the properties directly from SyntheticKeyboardEvent -- you need to specify the properties from the handler:

handleKeyUp: function(e) {
 console.log(e.type, e.which, e.timeStamp);
},

http://jsfiddle.net/BinaryMuse/B98Ar/

Solution 2 - Javascript

console.log() is aynchronous and by the time it access the event React already garbage collected it (it reuses the event for performance reasons).

For debugging purposes, the simplest thing to do is to tell React to not discard that event

e.persist() // NOTE: don't forget to remove it post debug
console.log(e)

I can't find an API documentation, the method is at least documented in the sources https://github.com/facebook/react/blob/c78464f/src/renderers/shared/stack/event/SyntheticEvent.js#L155

Solution 3 - Javascript

As Riccardo Galli points out correctly, the log object is already garbage collected at the time you access it in the console.

The solution I use is to just log a clone of the object, so it won't be garbage collected. Cloning can be done in a lot of ways, but since I use lodash, I log like this :

  handleKeyDown: function(e) {
      console.log(_.cloneDeep(e)));
    }

Solution 4 - Javascript

You can also extract the underlying (original) browser event from the Synthetic*Event wrapper via the nativeEvent property. E.g.,

handleKeyDown: function(e) {
  console.log('keyDown:event', e.nativeEvent);
},

(Just as with @Riccardo's note about e.persist(), it's unclear how you're supposed to know this without reading the React.js source code.)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncanteraView Question on Stackoverflow
Solution 1 - JavascriptcanteraView Answer on Stackoverflow
Solution 2 - JavascriptRiccardo GalliView Answer on Stackoverflow
Solution 3 - JavascriptPeterView Answer on Stackoverflow
Solution 4 - JavascriptchbrownView Answer on Stackoverflow