【问题标题】:How to access custom attributes from event object in React?如何从 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。我一直在搞砸一整天才意识到这一点。

标签: javascript facebook reactjs


【解决方案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.tagevent.target.getAttribute('data-tag');任何一个都可以。

      【讨论】:

      • react 0.13.3,IE10 event.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={() =&gt; this.removeTag(i)} 而不是 .bind

                【讨论】:

                • 但您不再获得通过的事件对象。
                • @chovy 如果我错了,请纠正我,但不是所有的 javascript 函数本质上都是可变的吗?我没有对此进行测试,但我认为“事件对象”仍在传递。它只是与以前不同的参数索引。以上述方式绑定就像unshifting 函数arguments 数组。如果“事件对象”位于索引 0,它现在将位于索引 1
                • @chovy 如果你需要,你可以。就做removeTag: function(i, evt) {
                • 它更简洁,但如果您执行大量绑定,所有这些绑定都会对性能造成影响。
                【解决方案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 上的样式。
                • 你怎么知道一个内部函数会包含事件参数?
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-06-13
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-11-09
                • 1970-01-01
                相关资源
                最近更新 更多