React'taki olay nesnesinden özel özelliklere nasıl erişilir?


214

React, http://facebook.github.io/react/docs/jsx-gotchas.html adresinde açıklandığı gibi özel özellikler oluşturabilir :

Özel bir öznitelik kullanmak istiyorsanız, veri- önüne önek eklemeniz gerekir.

<div data-custom-attribute="foo" />

Ve bu olay olay nesnesinden erişmek için bir yol bulamıyorum dışında harika bir haber:

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

Öğe ve data-özellik html ince biçiminde oluşturulur. Gibi standart özelliklere iyi styleerişilebilir event.target.style. Bunun yerine event.targetdenedim:

 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"]

bunların hiçbiri işe yaramadı.


1
Bir yorum yardımcı biri olabilir, ben React 16.7 yeniden ortaya değildir ve sadece bir mağaza (fe redux) onları değiştirdiyseniz ve bileşene bağlıysa bileşenin özel html özniteliklerini güncellemediğini öğrendim . Bu, bileşenin fe'ya sahip olduğu anlamına gelir, aria-modal=truedeğişiklikleri aria / veri öznitelikleri deposuna itersiniz, ancak sonuç ReactJ'ler aria /' yı güncellemeyeceğinden başka hiçbir şey değiştirilmez (bileşenin içeriği veya sınıfı veya değişkenleri gibi). bu bileşenlerde veri yıpranması. Bunu anlamak için bütün gün uğraşıyorum.
AlexNikonov

Yanıtlar:


171

İstenen sonucu belki de istediğinizden farklı bir şekilde elde etmenize yardımcı olmak için:

render: function() {
    ...
    <a data-tag={i} style={showStyle} onClick={this.removeTag.bind(null, i)}></a>
    ...
},
removeTag: function(i) {
    // do whatever
},

Dikkat edin bind(). Hepsi bu javascript olduğundan, böyle kullanışlı şeyler yapabilirsiniz. Bunları takip etmek için artık DOM düğümlerine veri eklememiz gerekmiyor.

IMO bu DOM olaylarına güvenmekten çok daha temiz.

Nisan 2017'yi güncelleyin: Bugünlerde onClick={() => this.removeTag(i)}bunun yerine yazarım.bind


17
ancak artık olay nesnesini geçiremezsiniz.
chovy

9
@chovy Eğer yanılıyorsam beni düzeltin ama tüm javascript fonksiyonları doğası gereği değişken değil mi? Bunu test etmedim, ancak "olay nesnesinin" hala geçildiğini varsayabilirim. Daha önce olduğu gibi aynı parametre dizininde DEĞİLDİR. Yukarıda özetlendiği gibi unshiftbir şekilde bağlanmak, işlev arguments dizisine benzer. "Olay nesnesi" dizinde 0olsaydı, şimdi dizinde olur 1.
Ryder Brooks

8
@chovy İhtiyacınız olursa yapabilirsiniz. Just doremoveTag: function(i, evt) {
Jared Forsyth

8
Daha temiz, ancak çok fazla yapıyorsanız tüm bu bağların bir performans isabeti var.
El Yobo


297

event.targetsize yerel DOM düğümünü verirse, özelliklere erişmek için normal DOM API'larını kullanmanız gerekir. İşte bununla ilgili dokümanlar: Veri özniteliklerini kullanma .

İkisinden birini event.target.dataset.tagveya event.target.getAttribute('data-tag'); biri çalışır.


24
tepki 0.13.3, IE10 event.target.datasettanımsız ama event.target.getAttribute('data-tag')çalışıyor. diğer tarayıcılar iyidir. Teşekkürler
Andrey Borisko

Bu yaklaşımda bir sorun var mı? Örneğin, kullanıcının hangi düğmeye bastığına bağlı olarak bir işleve bir dize geçirmek istiyorum. Her vaka için bileşenimde üç işlev yapmaktan kaçınmayı umuyordum.
Michael J.Calkins

4
Bu cevap, performans açısından kabul edilen cevaptan daha iyidir. Biz emin bu şekilde aracı yapıyor değil her işlemek yeni bir işlev oluşturun. Her render yeni bir işlev oluşturmayı atlamakla kalmaz, aynı zamanda işlev referansı her seferinde aynı olacağından, saf (veya not edilmiş) bileşenler farklı bir işlev olarak görmez. Bu nedenle, bileşen her seferinde gereksiz yere yeniden oluşturulmayacaktır. Özel bir uygulama bile shouldComponentUpdateişlev pervane tamamen göz ardı sürece aynı sorunu olurdu.
Michael Yaworski

Mükemmel çalışıyor
Ogbonna Vitalis

1
Ben daktilo yazıyorum. Benim durumumda kullanmak zorundaydımevent.currentTarget.getAttibute('data-tag')
karianpour

50

İşte bulduğum en iyi yol:

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

Bu öznitelikler, getNamedItem yöntemiyle kolayca erişebileceğiniz bir "NamedNodeMap" içinde depolanır.


4
Muhtemelen .valuegerçek değeri elde etmek için bir eklemek istiyorsunuz
Wikunia

.value@Wikunia'nın önerdiği gibi sonunda eklemek için cevabı düzenledim
fguillen

25

Veya bir kapatma kullanabilirsiniz:

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
Teşekkürler, Tudor. Çözümünüzü denedim ve bağlayıcı olmadan da çalışır. Bunu e.target'ta stilleri değiştirmek için kullandım.
andriy_sof

bir iç fonksiyonun olay argümanlarını içereceğini nasıl anlarsınız?
jack.the.ripper

20
// 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
diğer kodu anlamak için kodunuza bir açıklama ekleyin
Aniruddha Das

8

React v16.1.1 (2017) itibarıyla resmi çözüm şöyledir: https://reactjs.org/docs/handling-events.html#passing-arguments-to-event-handlers

TLDR: OP şunları yapmalıdır:

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

1
'Ben' nereden geliyor?
Freshchris

2
iOP'nin bir şekilde geçmek istediği özel özelliktir. aÖğe tanımlandığında kapsamda olan bir değişken .
1919'da tytk

OP'nin istediği bu değil. OnClick işleyicisiyle (a) öğesindeki öznitelik değerine erişmek istiyorlar.
Adrian

1
Demek istediğim, resmi çözümün, olay işleyicisi işlevini, öğe üzerinde bir veri özniteliği ayarlamak yerine kapsamdaki değişkenle tanımlamaktır. Bu, gerçekten isterseniz öğelerin özelliklerine erişmenizi engellemez, ancak React'taki bir değişkene erişmenin deyimsel yolu değildir.
19'da tytk

8
<div className='btn' onClick={(e) =>
     console.log(e.currentTarget.attributes['tag'].value)}
     tag='bold'>
    <i className='fa fa-bold' />
</div>

böylece e.currentTarget.attributes['tag'].valuebenim için çalışıyor


5

Veri özelliklerine böyle bir şeye erişebilirsiniz

event.target.dataset.tag

4

Bu tek kod satırı benim için sorunu çözdü:

event.currentTarget.getAttribute('data-tag')

3

React hakkında bilmiyorum, ancak genel durumda böyle özel nitelikleri iletebilirsiniz:

1) HTML etiketi içinde veri öneki olan yeni bir özellik tanımlayın

data-mydatafield = "asdasdasdaad"

2) ile javascript almak

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

Mine sürekli söyleyerek boş
Si8

3

Herkes React içinde event.target kullanmaya ve bir null değer bulmaya çalışıyorsa, bunun nedeni bir SyntheticEvent öğesinin event.target'ın yerini almasıdır. SyntheticEvent artık event.currentTarget.getAttribute ('data-username') gibi 'currentTarget' öğesini barındırıyor.

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

React bunu daha çok tarayıcıda çalışacak şekilde yapıyor gibi görünüyor. Bir nativeEvent özniteliği aracılığıyla eski özelliklere erişebilirsiniz.


3

Dom özelliklerini (yavaş olan) atamak yerine, değerinizi işleyicinizi oluşturan işleve bir parametre olarak iletmeniz yeterlidir:

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

harika bir yorum gibi görünüyor! dom özelliklerini atama çok daha yavaş nasıl görebilirim
Ido Bleicher

2

Event.target.dataset nesnesini kullanabilirsiniz . Bu size tüm veri özniteliklerine sahip nesneyi verecektir.


0

React'te html verilerine ihtiyacınız yoktur, başka bir işlev döndüren bir işlev kullanın; Bunun gibi özel parametreler göndermek çok basit ve özel veri ve olay erişebilirsiniz.

render: function() {
...
<a style={showStyle} onClick={this.removeTag(i)}></a>
...
removeTag: (i) => (event) => {
    this.setState({inputVal: i}); 
},
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.