จะเข้าถึงแอตทริบิวต์ที่กำหนดเองจากวัตถุเหตุการณ์ใน React ได้อย่างไร


214

React สามารถแสดงแอตทริบิวต์ที่กำหนดเองได้ตามที่อธิบายไว้ที่ http://facebook.github.io/react/docs/jsx-gotchas.html :

หากคุณต้องการใช้แอตทริบิวต์ที่กำหนดเองคุณควรใส่คำเสริมหน้าด้วย data-

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

ไม่สามารถใช้งานได้


1
อาจเป็นหนึ่งความคิดเห็นช่วยคนฉันพบตอบโต้ 16.7 ไม่แสดงผลและอัปเดตแอตทริบิวต์ html ที่กำหนดเองขององค์ประกอบหากคุณเปลี่ยนเฉพาะพวกเขาในร้านค้า (fe redux) และเชื่อมโยงกับส่วนประกอบ ซึ่งหมายความว่าองค์ประกอบมี fe aria-modal=trueคุณผลักดันการเปลี่ยนแปลง (เป็นเท็จ) ไปยังที่เก็บของคุณลักษณะaria / dataแต่ไม่มีอะไรเปลี่ยนแปลง (เช่นเนื้อหาของส่วนประกอบหรือคลาสหรือตัวแปรในนั้น) เนื่องจากผลลัพธ์ ReactJs จะไม่อัปเดตaria / data attrs ในส่วนประกอบนั้น ฉันยุ่งเกี่ยวกับทั้งวันเพื่อตระหนักว่า
AlexNikonov

คำตอบ:


171

เพื่อช่วยให้คุณได้รับผลลัพธ์ที่ต้องการในวิธีที่แตกต่างจากที่คุณถาม:

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

bind()แจ้งให้ทราบล่วงหน้า เพราะนี่คือจาวาสคริปต์ทั้งหมดคุณจึงสามารถทำสิ่งที่มีประโยชน์เช่นนั้นได้ เราไม่จำเป็นต้องแนบข้อมูลไปยังโหนด DOM เพื่อติดตามพวกเขาอีกต่อไป

IMO นี้สะอาดกว่าการใช้กิจกรรม DOM

อัปเดตเมษายน 2560:วันนี้ฉันจะเขียนonClick={() => this.removeTag(i)}แทน.bind


17
แต่คุณจะไม่ได้รับวัตถุเหตุการณ์ผ่านไป
chovy

9
@chovy โปรดแก้ไขฉันหากฉันผิด แต่ไม่ใช่ทุกฟังก์ชั่นจาวาสคริปต์ที่หลากหลายหรือไม่ ฉันยังไม่ได้ทดสอบสิ่งนี้ แต่ฉันจะถือว่า "เหตุการณ์วัตถุ" ยังคงถูกส่งผ่าน มันไม่ได้อยู่ที่ดัชนีพารามิเตอร์เดียวกันกับก่อนหน้านี้ การผูกไว้ในแฟชั่นตามที่ระบุไว้ข้างต้นเป็นเหมือนunshiftการเรียงลำดับฟังก์ชันอาร์กิวเมนต์ ถ้า "วัตถุเหตุการณ์" เป็นที่ดัชนีตอนนี้ก็จะเป็นที่ดัชนี0 1
ไรเดอร์บรูคส์

8
@ chovy คุณสามารถถ้าคุณต้องการมัน เพิ่งทำremoveTag: function(i, evt) {
Jared Forsyth

8
มันสะอาดกว่า แต่การผูกทั้งหมดนั้นมีผลงานยอดฮิตถ้าคุณทำมันเยอะ
El Yobo


297

event.targetให้โหนด DOM ดั้งเดิมแก่คุณจากนั้นคุณต้องใช้ DOM API ปกติเพื่อเข้าถึงแอตทริบิวต์ นี่คือเอกสารเกี่ยวกับวิธีการทำเช่นนั้น: การใช้แอตทริบิวต์ dataการใช้แอตทริบิวต์ข้อมูล

คุณสามารถทำอย่างใดอย่างหนึ่งevent.target.dataset.tagหรือevent.target.getAttribute('data-tag'); ใช้ได้ทั้งงาน


24
ตอบสนอง 0.13.3, IE10 event.target.datasetไม่ได้ถูกกำหนด แต่event.target.getAttribute('data-tag')ใช้ได้ เบราว์เซอร์อื่นนั้นใช้ได้ ขอบคุณ
Andrey Borisko

มีอะไรผิดปกติกับวิธีนี้หรือไม่? ตัวอย่างเช่นขึ้นอยู่กับปุ่มที่ผู้ใช้กดฉันต้องการส่งสตริงไปยังฟังก์ชัน ฉันหวังว่าจะหลีกเลี่ยงการทำสามหน้าที่ในองค์ประกอบของฉันสำหรับแต่ละกรณี
Michael J. Calkins

4
คำตอบนี้ดีกว่าคำตอบที่ยอมรับในด้านประสิทธิภาพ การทำอย่างนี้หมายความว่าเราไม่ได้สร้างฟังก์ชั่นใหม่ในทุก ๆ การเรนเดอร์ ไม่เพียงแค่ข้ามการสร้างฟังก์ชั่นใหม่ในแต่ละการแสดงผล แต่เนื่องจากการอ้างอิงฟังก์ชั่นจะเหมือนกันทุกครั้งที่องค์ประกอบบริสุทธิ์ (หรือบันทึก) จะไม่เห็นว่ามันเป็นฟังก์ชั่นที่แตกต่างกัน ดังนั้นจึงไม่จำเป็นต้องแสดงองค์ประกอบทั้งหมดซ้ำทุกครั้งโดยไม่จำเป็น แม้แต่การนำไปปฏิบัติที่กำหนดเองshouldComponentUpdateจะมีปัญหาเดียวกันเว้นแต่คุณจะเพิกเฉยต่อฟังก์ชันเสา
Michael Yaworski

ทำงานได้อย่างสมบูรณ์แบบ
Ogbonna Vitalis

1
ฉันใช้ typescript ในกรณีของฉันฉันต้องใช้event.currentTarget.getAttibute('data-tag')
karianpour

50

นี่คือวิธีที่ดีที่สุดที่ฉันพบ:

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

คุณลักษณะเหล่านั้นจะถูกเก็บไว้ใน "NamedNodeMap" ซึ่งคุณสามารถเข้าถึงได้อย่างง่ายดายด้วยเมธอด getNamedItem


4
คุณอาจต้องการเพิ่ม a .valueเพื่อรับค่าจริง
Wikunia

ฉันได้แก้ไขคำตอบเพื่อเพิ่ม.valueในตอนท้ายตามที่ @Wikunia ได้แนะนำ
fguillen

25

หรือคุณสามารถใช้การปิด:

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
andriy_sof

คุณจะรู้ได้อย่างไรว่าฟังก์ชั่นด้านในจะมีเหตุการณ์ที่เกิดขึ้น?
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
เพิ่มคำอธิบายลงในรหัสของคุณเพื่อให้คนอื่นเข้าใจรหัส
Aniruddha Das

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}); 
}

1
'i' มาจากไหน
Freshchris

2
iเป็นแอตทริบิวต์ที่กำหนดเองที่ OP ต้องการผ่านอย่างใด มันเป็นตัวแปรที่อยู่ในขอบเขตเมื่อaองค์ประกอบถูกกำหนด
tytk

นั่นไม่ใช่สิ่งที่ OP ต้องการ พวกเขาต้องการเข้าถึงค่าคุณลักษณะบนองค์ประกอบ (a) ด้วยตัวจัดการ onClick
ออกแบบโดย Adrian

1
ประเด็นของฉันคือการแก้ปัญหาอย่างเป็นทางการคือการกำหนดฟังก์ชั่นตัวจัดการเหตุการณ์ด้วยตัวแปรในขอบเขตแทนที่จะตั้งค่าแอตทริบิวต์ข้อมูลในองค์ประกอบ สิ่งนี้จะไม่หยุดคุณไม่ให้เข้าถึงแอตทริบิวต์ขององค์ประกอบหากคุณต้องการจริงๆ แต่นั่นไม่ใช่วิธีการเข้าถึงตัวแปรใน React
tytk

8
<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การทำงานสำหรับฉัน


5

คุณสามารถเข้าถึงแอตทริบิวต์ข้อมูลบางอย่างเช่นนี้

event.target.dataset.tag


3

ฉันไม่รู้เกี่ยวกับ React แต่ในกรณีทั่วไปคุณสามารถส่งแอตทริบิวต์ที่กำหนดเองดังนี้:

1) กำหนดภายใน html- แท็กแอตทริบิวต์ใหม่ด้วย data- คำนำหน้า

data-mydatafield = "asdasdasdaad"

2) รับจาก javascript ด้วย

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

ฉันคอยบอกว่าโมฆะ
Si8

3

หากใครพยายามใช้ event.target ใน React และค้นหาค่า Null นั่นเป็นเพราะ SyntheticEvent ได้แทนที่ event.target ตอนนี้ SyntheticEvent จะเก็บ 'currentTarget' เช่นใน event.currentTarget.getAttribute ('data-username')

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

ดูเหมือนว่า React จะทำเช่นนี้เพื่อให้สามารถทำงานกับเบราว์เซอร์อื่น ๆ คุณสามารถเข้าถึงคุณสมบัติเก่าผ่านแอตทริบิวต์ nativeEvent


3

ลองแทนที่จะกำหนดคุณสมบัติ dom (ซึ่งช้า) เพียงแค่ส่งค่าของคุณเป็นพารามิเตอร์เพื่อทำงานที่สร้างตัวจัดการของคุณจริง:

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

ดูเหมือนว่าเป็นความคิดเห็นที่ดี! ฉันจะดูได้อย่างไรว่าช้ากว่าการกำหนดคุณสมบัติ dom
Ido Bleicher

2

คุณสามารถใช้วัตถุevent.target.dataset สิ่งนี้จะให้วัตถุกับแอตทริบิวต์ข้อมูลทั้งหมด


0

ในการตอบสนองคุณไม่ต้องการข้อมูล html ให้ใช้ฟังก์ชันส่งคืนฟังก์ชันอื่น เช่นนี้มันง่ายมากที่จะส่งพารามิเตอร์ที่กำหนดเองและคุณสามารถเข้าถึงข้อมูลที่กำหนดเองและเหตุการณ์

render: function() {
...
<a style={showStyle} onClick={this.removeTag(i)}></a>
...
removeTag: (i) => (event) => {
    this.setState({inputVal: i}); 
},
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.