Bagaimana cara mengakses atribut khusus dari objek acara di Bereaksi?


214

Bereaksi mampu membuat atribut khusus seperti yang dijelaskan di http://facebook.github.io/react/docs/jsx-gotchas.html :

Jika Anda ingin menggunakan atribut khusus, Anda harus awalan dengan data-.

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

Dan itu berita bagus kecuali saya tidak dapat menemukan cara untuk mengaksesnya dari objek acara misalnya:

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

Elemen dan data-properti membuat html baik-baik saja. Properti standar seperti styledapat diakses dengan event.target.stylebaik. Alih-alih event.targetsaya mencoba:

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

tidak ada yang berhasil.


1
Mungkin satu komentar membantu seseorang, saya menemukan Bereaksi 16.7 tidak membuat rerender dan memperbarui atribut html kustom komponen jika Anda hanya mengubahnya di toko (fe redux) dan terkait dengan komponen. Ini berarti komponen memiliki fitur aria-modal=true, Anda mendorong perubahan (ke false) ke penyimpanan atribut aria / data , tetapi tidak ada yang lain yang diubah (seperti konten komponen atau kelas atau variabel di sana) karena hasilnya ReactJs tidak akan memperbarui aria / attr data dalam komponen itu. Saya telah bermain-main sepanjang hari untuk menyadari hal itu.
AlexNikonov

Jawaban:


171

Untuk membantu Anda mendapatkan hasil yang diinginkan dengan cara yang mungkin berbeda dari yang Anda tanyakan:

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

Perhatikan bind() . Karena ini semua javascript, Anda dapat melakukan hal-hal praktis seperti itu. Kami tidak perlu lagi melampirkan data ke node DOM untuk melacaknya.

IMO ini jauh lebih bersih daripada mengandalkan acara DOM.

Perbarui April 2017: Hari-hari ini saya akan menulis onClick={() => this.removeTag(i)}sebagai ganti.bind


17
tetapi Anda tidak lagi mendapatkan objek acara berlalu.
chovy

9
@chovy Harap perbaiki saya jika saya salah tetapi tidak semua fungsi javascript inheren variadic? Saya belum menguji ini, tapi saya akan menganggap "objek acara" masih dilewati. Hanya saja TIDAK pada indeks parameter yang sama seperti sebelumnya. Mengikat dengan cara seperti diuraikan di atas adalah seperti unshifting array argumen fungsi . Jika "objek acara" berada di indeks 0sekarang akan di indeks 1.
Ryder Brooks

8
@ chovy Anda bisa jika Anda membutuhkannya. Lakukan sajaremoveTag: function(i, evt) {
Jared Forsyth

8
Ini lebih bersih, tetapi semua ikatan itu memiliki kinerja yang baik jika Anda melakukan banyak hal.
El Yobo


297

event.targetmemberi Anda simpul DOM asli, maka Anda perlu menggunakan DOM API biasa untuk mengakses atribut. Berikut adalah dokumen tentang cara melakukannya: Menggunakan atribut data .

Anda dapat melakukan salah satu event.target.dataset.tagatau event.target.getAttribute('data-tag'); salah satu yang berfungsi.


24
bereaksi 0.13.3, IE10 event.target.datasettidak didefinisikan tetapi event.target.getAttribute('data-tag')berfungsi. browser lainnya baik-baik saja. Terima kasih
Andrey Borisko

Apakah ada yang salah dengan pendekatan ini? Misalnya tergantung pada tombol apa yang ditekan pengguna, saya ingin meneruskan sebuah string ke suatu fungsi. Saya berharap untuk tidak membuat tiga fungsi dalam komponen saya untuk setiap kasus.
Michael J. Calkins

4
Jawaban ini lebih baik daripada yang diterima dalam hal kinerja. Melakukannya dengan cara ini berarti bahwa kami tidak membuat fungsi baru pada setiap render. Tidak hanya melompati pembuatan fungsi baru setiap render, tetapi karena referensi fungsi akan sama setiap kali, komponen murni (atau memoized) tidak akan melihatnya sebagai fungsi yang berbeda. Oleh karena itu, itu tidak akan perlu merender ulang seluruh komponen setiap saat. Bahkan implementasi kustom shouldComponentUpdateakan memiliki masalah yang sama kecuali jika Anda hanya mengabaikan prop fungsi.
Michael Yaworski

Bekerja dengan sangat baik
Ogbonna Vitalis

1
Saya menggunakan naskah. Dalam kasus saya, saya harus menggunakanevent.currentTarget.getAttibute('data-tag')
karianpour

50

Inilah cara terbaik yang saya temukan:

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

Atribut tersebut disimpan dalam "NamedNodeMap", yang dapat Anda akses dengan mudah dengan metode getNamedItem.


4
Anda mungkin ingin menambahkan .valueuntuk mendapatkan nilai aktual
Wikunia

Saya telah mengedit jawaban untuk menambahkan .valuedi bagian akhir seperti yang disarankan
@Wikunia

25

Atau Anda dapat menggunakan penutupan:

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
Terima kasih, Tudor. Mencoba solusi Anda dan itu berfungsi bahkan tanpa mengikat. Saya menggunakannya untuk beralih gaya di e.target.
andriy_sof

bagaimana Anda tahu fungsi dalam akan berisi argumen acara?
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
tambahkan beberapa deskripsi ke kode Anda untuk membuat orang lain memahami kode
Aniruddha Das

8

Pada React v16.1.1 (2017), berikut adalah solusi resmi: https://reactjs.org/docs/handling-events.html#passing-arguments-to-event-handlers

TLDR: OP harus melakukan:

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

1
Dari mana 'i' berasal?
Freshchris

2
iadalah atribut khusus yang OP ingin sampaikan. Ini beberapa variabel yang ada dalam ruang lingkup ketika aelemen didefinisikan.
tytk

Bukan itu yang diinginkan OP. Mereka ingin mengakses nilai atribut pada elemen (a) dengan penangan onClick.
Desain oleh Adrian

1
Maksud saya adalah bahwa solusi resmi adalah untuk menentukan fungsi event-handler dengan variabel dalam lingkup, daripada menetapkan atribut data pada elemen. Ini tidak menghentikan Anda dari mengakses atribut elemen jika Anda benar-benar ingin, tetapi itu bukan cara idiomatis untuk mengakses variabel di Bereaksi.
tytk

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

jadi e.currentTarget.attributes['tag'].valuebekerja untuk saya



4

Baris kode tunggal ini memecahkan masalah bagi saya:

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

3

Saya tidak tahu tentang Bereaksi, tetapi dalam kasus umum Anda dapat memberikan atribut khusus seperti ini:

1) mendefinisikan di dalam html-tag atribut baru dengan awalan data

data-mydatafield = "asdasdasdaad"

2) dapatkan dari javascript dengan

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


3

Jika ada yang mencoba menggunakan event.target di Bereaksi dan menemukan nilai nol, itu karena SyntheticEvent telah menggantikan event.target. SyntheticEvent sekarang memiliki 'currentTarget', seperti di event.currentTarget.getAttribute ('data-username').

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

Sepertinya React melakukan ini sehingga berfungsi di lebih banyak browser. Anda dapat mengakses properti lama melalui atribut nativeEvent.


3

Coba alih-alih menetapkan properti dom (yang lambat) cukup berikan nilai Anda sebagai parameter untuk berfungsi yang sebenarnya membuat penangan Anda:

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

sepertinya komentar yang bagus! bagaimana saya bisa melihat bahwa itu jauh lebih lambat menetapkan properti dom
Ido Bleicher

2

Anda cukup menggunakan objek event.target.dataset . Ini akan memberi Anda objek dengan semua atribut data.


0

Di Bereaksi Anda tidak memerlukan data html, gunakan fungsi untuk mengembalikan fungsi lainnya; seperti ini, sangat sederhana kirim params khusus dan Anda dapat mengakses data khusus dan acara.

render: function() {
...
<a style={showStyle} onClick={this.removeTag(i)}></a>
...
removeTag: (i) => (event) => {
    this.setState({inputVal: i}); 
},
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.