如何从 React 中的事件对象访问自定义属性?
Posted
技术标签:
【中文标题】如何从 React 中的事件对象访问自定义属性?【英文标题】:How to access custom attributes from event object in React? 【发布时间】:2013-12-21 02:02:57 【问题描述】:React 能够呈现自定义属性,如在 http://facebook.github.io/react/docs/jsx-gotchas.html:
如果你想使用自定义属性,你应该在它前面加上 数据-。
<div data-custom-attribute="foo" />
这是个好消息,只是我找不到从事件对象访问它的方法,例如:
render: function()
...
<a data-tag=i style=showStyle onClick=this.removeTag></a>
...
removeTag: function(event)
this.setState(inputVal: event.target????);
,
元素和data-
属性可以在html 中呈现。 style
等标准属性可以作为 event.target.style
正常访问。
而不是event.target
我试过了:
event.target.props.data.tag
event.target.props.data["tag"]
event.target.props["data-tag"]
event.target.data.tag
event.target.data["tag"]
event.target["data-tag"]
这些都不起作用。
【问题讨论】:
可能是一条评论对某人有帮助,我发现 React 16.7 doesnt rerenders 并更新组件的自定义 html 属性,如果您只更改了它们存储(fe redux)并绑定到组件。这意味着组件具有 fearia-modal=true
,您将更改(为 false)推送到 aria/data 属性的存储区,但没有其他任何更改(例如组件的内容或类或变量) ) 结果 ReactJs 不会更新该组件中的 aria/data attrs。我一直在搞砸一整天才意识到这一点。
【参考方案1】:
我认为建议绑定所有需要使用 this.setState 方法的方法,该方法在 React.Component 类中定义,在构造函数中,在你的如果你的构造函数应该是这样的
constructor()
super()
//This binding removeTag is necessary to make `this` work in the callback
this.removeTag = this.removeTag.bind(this)
removeTag(event)
console.log(event.target)
//use Object destructuring to fetch all element values''
const style, dataset = event.target
console.log(style)
console.log(dataset.tag)
render()
...
<a data-tag=i style=showStyle onClick=this.removeTag.bind(null, i)></a>
...,
有关对象解构的更多参考 https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Operators/Destructuring_assignment#Object_destructuring
【讨论】:
【参考方案2】:您可以简单地使用 event.target.dataset 对象。这将为您提供具有所有数据属性的对象。
【讨论】:
【参考方案3】:event.target
为您提供原生 DOM 节点,然后您需要使用常规 DOM API 来访问属性。以下是有关如何执行此操作的文档:Using data attributes。
您可以选择event.target.dataset.tag
或event.target.getAttribute('data-tag')
;任何一个都可以。
【讨论】:
react 0.13.3,IE10event.target.dataset
未定义,但 event.target.getAttribute('data-tag')
有效。其他浏览器都很好。谢谢
这种方法有什么问题吗?例如,根据用户按下的按钮,我想将字符串传递给函数。我希望避免在每种情况下在我的组件中创建三个函数。
这个答案在性能方面比公认的要好。这样做意味着我们不在每次渲染时都创建一个新函数。它不仅跳过每次渲染创建一个新函数,而且由于每次函数引用都是相同的,纯(或记忆化)组件不会将其视为不同的函数。因此,它不会每次都不必要地重新渲染整个组件。即使是 shouldComponentUpdate
的自定义实现也会有同样的问题,除非你完全忽略了函数 prop。
我使用打字稿。就我而言,我不得不使用event.currentTarget.getAttibute('data-tag')
这个答案不正确,结果不可靠。请使用e.currentTarget.getAttribute()
【参考方案4】:
这一行代码为我解决了问题:
event.currentTarget.getAttribute('data-tag')
【讨论】:
【参考方案5】:你可以像这样访问数据属性
event.target.dataset.tag
【讨论】:
【参考方案6】:尝试将您的值作为参数传递给实际创建处理程序的函数,而不是分配 dom 属性(这很慢):
render: function()
...
<a style=showStyle onClick=this.removeTag(i)></a>
...
removeTag = (customAttribute) => (event) =>
this.setState(inputVal: customAttribute);
【讨论】:
看起来很棒!我怎么能看到分配 dom 属性要慢得多【参考方案7】:<div className='btn' onClick=(e) =>
console.log(e.currentTarget.attributes['tag'].value)
tag='bold'>
<i className='fa fa-bold' />
</div>
所以e.currentTarget.attributes['tag'].value
为我工作
【讨论】:
【参考方案8】:从 React v16.1.1 (2017) 开始,这里是官方解决方案:https://reactjs.org/docs/handling-events.html#passing-arguments-to-event-handlers
TLDR: OP 应该这样做:
render: function()
...
<a style=showStyle onClick=(e) => this.removeTag(i, e)></a>
...
removeTag: function(i, event)
this.setState(inputVal: i);
【讨论】:
“我”从何而来?i
是 OP 想要以某种方式传入的自定义属性。这是定义 a
元素时范围内的一些变量。
这不是 OP 想要的。他们想使用 onClick 处理程序访问元素 (a) 上的属性值。
我的意思是,官方的解决方案是在范围内定义带有变量的事件处理函数,而不是在元素上设置数据属性。如果你真的想要,这不会阻止你访问元素的属性,但这不是在 React 中访问变量的惯用方式。【参考方案9】:
如果有人试图在 React 中使用 event.target 并找到一个空值,那是因为 SyntheticEvent 已经替换了 event.target。 SyntheticEvent 现在包含“currentTarget”,例如在 event.currentTarget.getAttribute('data-username') 中。
https://facebook.github.io/react/docs/events.html
看起来 React 这样做是为了让它可以在更多浏览器上运行。您可以通过 nativeEvent 属性访问旧属性。
【讨论】:
【参考方案10】:// Method inside the component
userClick(event)
let tag = event.currentTarget.dataset.tag;
console.log(tag); // should return Tagvalue
// when render element
<a data-tag="TagValue" onClick=this.userClick>Click me</a>
【讨论】:
在你的代码中添加一些描述,让其他人理解代码【参考方案11】:在 React 中你不需要 html 数据,使用一个函数返回另一个函数;像这样发送自定义参数非常简单,您可以访问自定义数据和事件。
render: function()
...
<a style=showStyle onClick=this.removeTag(i)></a>
...
removeTag: (i) => (event) =>
this.setState(inputVal: i);
,
【讨论】:
【参考方案12】:为了帮助您以可能与您所要求的方式不同的方式获得所需的结果:
render: function()
...
<a data-tag=i style=showStyle onClick=this.removeTag.bind(null, i)></a>
...
,
removeTag: function(i)
// do whatever
,
注意bind()
。因为这都是javascript,所以你可以做这样的方便的事情。我们不再需要将数据附加到 DOM 节点来跟踪它们。
IMO 这比依赖 DOM 事件要干净得多。
2017 年 4 月更新:这些天我会写 onClick=() => this.removeTag(i)
而不是 .bind
【讨论】:
但您不再获得通过的事件对象。 @chovy 如果我错了,请纠正我,但不是所有的 javascript 函数本质上都是可变的吗?我没有对此进行测试,但我认为“事件对象”仍在传递。它只是与以前不同的参数索引。以上述方式绑定就像unshift
ing 函数arguments 数组。如果“事件对象”位于索引 0
,它现在将位于索引 1
。
@chovy 如果你需要,你可以。就做removeTag: function(i, evt)
它更简洁,但如果您执行大量绑定,所有这些绑定都会对性能造成影响。
github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/…【参考方案13】:
这是我找到的最好方法:
var attribute = event.target.attributes.getNamedItem('data-tag').value;
这些属性存储在“NamedNodeMap”中,您可以使用 getNamedItem 方法轻松访问。
【讨论】:
您可能想添加.value
以获取实际值
我已经编辑了答案,按照@Wikunia 的建议在末尾添加了.value
【参考方案14】:
我不了解 React,但在一般情况下,您可以像这样传递自定义属性:
1) 在 html-tag 中定义一个带有 data- 前缀的新属性
data-mydatafield = "asdasdasdaad"
2) 使用
从 javascript 中获取e.target.attributes.getNamedItem("data-mydatafield").value
【讨论】:
我的一直说空【参考方案15】:或者你可以使用闭包:
render: function()
...
<a data-tag=i style=showStyle onClick=this.removeTag(i)></a>
...
,
removeTag: function (i)
return function (e)
// and you get both `i` and the event `e`
.bind(this) //important to bind function
【讨论】:
谢谢,都铎王朝。尝试了您的解决方案,它甚至可以在没有绑定的情况下工作。我用它来切换 e.target 上的样式。 你怎么知道一个内部函数会包含事件参数?以上是关于如何从 React 中的事件对象访问自定义属性?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 TypeScript v2.x 中从自定义 React 组件公开“通用”事件