Как получить доступ к пользовательским атрибутам из объекта события в React?

146

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- свойство render в html отлично. Стандартные свойства, такие как style, могут быть доступны как event.target.style fine. Вместо 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"]

никто из них не работал.

  • 0
    Может быть, один комментарий поможет кому-то, я обнаружил, что React 16.7 не рендерит и не обновляет настраиваемые html-атрибуты компонента, если вы изменили только их в хранилище (например, избыточный) и привязали к компоненту. Это означает, что компонент имеет a aria-modal=true , вы помещаете изменения (в ложь) в хранилище атрибутов aria / data , но ничего больше не изменяется (например, содержимое компонента или класс или переменные в нем) как результат ReactJs не будет обновлять атрибуты aria / data в этих компонентах. Я целый день возился с этим, чтобы понять это.
Теги:
facebook

13 ответов

139
Лучший ответ

Чтобы помочь вам получить желаемый результат, возможно, по-другому, чем вы спросили:

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 года: В настоящее время я пишу onClick={() => this.removeTag(i)} вместо .bind

  • 15
    но вы больше не получаете переданный объект события.
  • 9
    @chovy Пожалуйста, поправьте меня, если я ошибаюсь, но разве все функции javascript не являются вариативными? Я не проверял это, но я бы предположил, что «объект события» все еще передается. Это просто НЕ с тем же индексом параметров, что был ранее. Связывание способом, описанным выше, похоже на unshift массива аргументов функции. Если бы «объект события» был с индексом 0 , теперь он был бы с индексом 1 .
Показать ещё 14 комментариев
208

event.target предоставляет вам собственный DOM node, тогда вам нужно использовать обычные API DOM для доступа к атрибутам. Ниже приведены документы о том, как это сделать:

https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes#JavaScript_Access

Вы можете сделать либо event.target.dataset.tag, либо event.target.getAttribute('data-tag'); либо работает.

  • 15
    реагировать 0.13.3, IE10 event.target.dataset не определен, но event.target.getAttribute('data-tag') работает. другие браузеры в порядке. Спасибо
  • 0
    Что-то не так с этим подходом? Например, в зависимости от того, какую кнопку нажимает пользователь, я хочу передать строку в функцию. Я надеялся избежать создания трех функций в моем компоненте для каждого случая.
Показать ещё 2 комментария
42

Вот лучший способ, который я нашел:

var attribute = event.target.attributes.getNamedItem('data-tag').value;

Эти атрибуты хранятся в "NamedNodeMap", к которым вы легко можете получить доступ с помощью метода getNamedItem.

  • 4
    Вы, вероятно, хотите добавить .value чтобы получить фактическое значение
  • 0
    Я отредактировал ответ, добавив .value в конце, как предложил @Wikunia
22

Или вы можете использовать закрытие:

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 
}
  • 3
    Спасибо, Тюдор. Опробовал ваше решение, и оно работает даже без привязки. Я использовал его для переключения стилей на e.target.
  • 0
    Как вы знаете, внутренняя функция будет содержать аргументы события?
7

Начиная с React v16.1.1 (2017), вот официальное решение: https://reactjs.org/docs/handling-events.html#passing-arguments-to-event-handlers

TL;DR: OP должен делать:

render: function() {
...
<a style={showStyle} onClick={(e) => this.removeTag(i, e)}></a>
...
removeTag: function(i, event) {
    this.setState({inputVal: i}); 
}
  • 0
    Откуда пришло «я»?
  • 1
    i - это пользовательский атрибут, который OP хотел как-то передать. Это некоторая переменная, которая находится в области видимости, когда a элемент.
7
// 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>
  • 1
    добавить некоторое описание в ваш код, чтобы другие поняли код
3
<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 у меня работает

2

Я не знаю об React, но в общем случае вы можете передать такие пользовательские атрибуты, как это:

1) определите внутри html-тега новый атрибут с префиксом префикса

data-mydatafield = "asdasdasdaad"

2) получить от javascript с помощью

e.target.attributes.getNamedItem("data-mydatafield").value 
1

Если кто-то пытается использовать event.target в React и найти нулевое значение, это потому, что SyntheticEvent заменил event.target. SyntheticEvent теперь содержит "currentTarget", например, в event.currentTarget.getAttribute( "data-username" ).

https://facebook.github.io/react/docs/events.html

Похоже, что React делает это так, что он работает во многих браузерах. Вы можете получить доступ к старым свойствам с помощью атрибута nativeEvent.

0

Попробуйте вместо присвоения свойств dom (что медленно) просто передайте свое значение в качестве параметра функции, которая фактически создает ваш обработчик:

render: function() {
...
<a style={showStyle} onClick={this.removeTag(i)}></a>
...
removeTag = (customAttribute) => (event) => {
    this.setState({inputVal: customAttribute});
}
0

как получить значение атрибута элемента реакции, а не элемента html. весь метод, описанный в верхней части страницы, может получить значение атрибута элемента после рендера, то есть получить значение атрибута html элемента. но мне нужно получить значение атрибута элемента реагировать. пожалуйста, не говорите мне использовать состояние. я хочу получить аттрибут

-1

В React вам не нужны данные html, используйте функцию, возвращающую другую функцию; например, это очень простая отправка настраиваемых параметров, и вы можете получить пользовательские данные и событие.

render: function() {
...
<a style={showStyle} onClick={this.removeTag(i)}></a>
...
removeTag: (i) => (event) => {
    this.setState({inputVal: i}); 
},
-1

Это тоже работает:

var attribute = $(event.target.attributes ['data-tag']). val();

Ещё вопросы

Сообщество Overcoder
Наверх
Меню