React:键盘事件处理程序全部'空'

时间:2014-03-02 02:18:14

标签: javascript reactjs react-jsx

我无法让任何React SyntheticKeyboardEvent处理程序为事件属性注册除null之外的任何内容。

我已经在小提琴中分离了组件,并且获得了与我的应用程序相同的结果。谁能看到我做错了什么?

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

4 个答案:

答案 0 :(得分:62)

BinaryMuse在IRC上提供了答案。事实证明这只是一个怪癖;您无法直接从SyntheticKeyboardEvent读取属性 - 您需要从处理程序中指定属性:

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

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

答案 1 :(得分:24)

console.log()是异步的,当它访问事件时,React已经垃圾收集它(它出于性能原因重新使用该事件)。

出于调试目的,最简单的方法是告诉React不要丢弃该事件

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

我无法找到API文档,该方法至少记录在来源https://github.com/facebook/react/blob/c78464f/src/renderers/shared/stack/event/SyntheticEvent.js#L155

答案 2 :(得分:2)

正如Riccardo Galli指出的那样,日志对象在您在控制台中访问时已经被垃圾收集了。

我使用的解决方案是只记录对象的克隆,因此不会进行垃圾回收。克隆可以通过很多方式完成,但由于我使用lodash,我会像这样记录:

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

答案 3 :(得分:1)

您还可以通过Synthetic*Event属性从nativeEvent包装器中提取基础(原始)浏览器事件。如,

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

(就像@ Riccardo关于e.persist()的说明一样,在不阅读React.js源代码的情况下,您不清楚如何知道这一点。)