2014-10-11 300 views
17
module.exports = React.createClass({ 
    click: function(e){ 
    console.log(e) 
    }, 
    render: function() { 
    return div({className: "thing1", children:[ 
     div({className: "thing2", onClick: this.click}) 
    ]}) 
    } 
}) 

传递给的事件包含所有制作的点击对象,但值为空。React.js onClick事件返回所有空值

Object { dispatchConfig: null, dispatchMarker: null, nativeEvent: null, type: null, target: null, currentTarget: null, eventPhase: null, bubbles: null, cancelable: null, timeStamp: null, 22 more… } 

任何想法?

回答

22

出于性能原因反应池事件对象。因此,它从池中取出一个事件对象,在其上设置属性,调用您的处理程序,然后将所有属性设置为null,以便可以重用它。

这几乎只是一个问题,因为控制台懒洋洋地评估你记录的对象。你可以做一个事件对象的浅层克隆来使console.log工作。

出于调试目的,

console.shallowCloneLog = function(){ 
    var typeString = Function.prototype.call.bind(Object.prototype.toString) 
    console.log.apply(console, Array.prototype.map.call(arguments, function(x){ 
    switch (typeString(x).slice(8, -1)) { 
     case 'Number': case 'String': case 'Undefined': case 'Null': case 'Boolean': return x; 
     case 'Array': return x.slice(); 
     default: 
     var out = Object.create(Object.getPrototypeOf(x)); 
     out.constructor = x.constructor; 
     for (var key in x) { 
      out[key] = x[key]; 
     } 
     Object.defineProperty(out, 'constructor', {value: x.constructor}); 
     return out; 
    } 
    })); 
} 
console.shallowCloneLog(e) 
+0

谢谢,理解,很好的答案。 – boom 2014-10-11 19:54:41

+7

为了简单的调试目的,在记录事件之前调用事件上的persist()可能是一个很好的解决方法。 – 2014-10-12 02:41:49

3

如果您有jQuery的方便,只需拨打:

console.log('e: ', $.extend({}, e)); 
+4

一个可能更有可能有Object.assign: 'console.log(Object.assign({},ev));' – 2016-03-22 14:03:17

2

如果您在使用阶段-2或向上的ES6功能console.log({...e})将与上面的浅层克隆实现相同。

+0

你能解释一下代码的工作原理吗? – 2018-01-30 08:30:35

6

事件处理程序将传递SyntheticEvent的实例。 SyntheticEvent被合并。这意味着SyntheticEvent对象将被重用,并且在事件回调被调用之后,所有属性都将被取消。

如果你想在一个异步的方式来访问事件属性,你应该叫event.persist()

func(e){ 
    e.persist(); 
    console.log(e);// all the properties are retained 
} 

render() { 
    return(
     <div onMouseOver={this.func}> 
     //rest of the logic 
     </div> 
    ); 
}