React:键盘事件处理程序全部为“空”
Posted
技术标签:
【中文标题】React:键盘事件处理程序全部为“空”【英文标题】:React: Keyboard Event Handlers All 'Null' 【发布时间】:2014-04-03 02:26:28 【问题描述】:我无法让任何 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);
【问题讨论】:
如已接受的答案中所述:您不能直接记录事件对象。但是在使用 ES2015 内省所有可用属性时,您可以使用像console.log(...e);
这样的属性传播。
【参考方案1】:
BinaryMuse 在 IRC 上提供了答案。原来这只是一个怪癖。您不能直接从 SyntheticKeyboardEvent
读取属性——您需要从处理程序中指定属性:
handleKeyUp: function(e)
console.log(e.type, e.which, e.timeStamp);
,
http://jsfiddle.net/BinaryMuse/B98Ar/
【讨论】:
发生这种情况是因为 React 重用了事件对象以提高性能,因此在控制台查找它们时属性为null
。如果 Chrome 在记录时立即复制对象,您就不会遇到这个“问题”。
节目有点晚了,但假设我想捕捉这个事件,setState(someFunc, callbackWithEvent)。有没有办法克隆这个事件,以便 callbackWithEvent 接收合成事件?
如果您想查看事件在控制台记录时的状态,而不是在控制台中查看时的状态,请将其记录为 JSON。这通过值而不是引用来复制它。 console.log(JSON.stringify(event))
@CharlieMartin 绝招!这让我们对问题有了更多的反省。
嗯。这对我不起作用。处理程序只是没有被调用。可能是什么问题?【参考方案2】:
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
【讨论】:
我试图获取触摸事件的 'X' 值,但即使正确捕获常规鼠标点击,它仍然保持为空。这解决了我的问题。谢谢!【参考方案3】:正如 Riccardo Galli 正确指出的那样,当您在控制台中访问日志对象时,它已经被垃圾回收了。
我使用的解决方案是只记录对象的克隆,这样它就不会被垃圾收集。可以通过多种方式进行克隆,但由于我使用的是 lodash,所以我的日志是这样的:
handleKeyDown: function(e)
console.log(_.cloneDeep(e)));
【讨论】:
【参考方案4】:您还可以通过nativeEvent
属性从Synthetic*Event
包装器中提取底层(原始)浏览器事件。例如,
handleKeyDown: function(e)
console.log('keyDown:event', e.nativeEvent);
,
(就像@Riccardo 关于e.persist()
的注释一样,如果不阅读 React.js 源代码,您将不清楚如何知道这一点。)
【讨论】:
以上是关于React:键盘事件处理程序全部为“空”的主要内容,如果未能解决你的问题,请参考以下文章
在 React 中的 onFocus 期间区分键盘和鼠标事件