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.styleevent.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
1つのコメントが誰かを助けるかもしれませんが、ストアでそれらのみを変更し(fe redux)、コンポーネントに関連付けられている場合、React 16.7 がコンポーネントのカスタムHTML属性を再レンダリングおよび更新しないことがわかりました 。これは、コンポーネントがfeを持っていることを意味します。aria-modal=true変更は(falseに)aria / data属性のストアにプッシュされますが、結果ReactJはaria /を更新しないため、他の何も変更されません(コンポーネントのコンテンツ、クラスまたは変数など)。 そのコンポーネントのデータ属性。私はそれを実現するために一日中ぐるぐる回っています。
AlexNikonov

回答:


171

おそらくあなたが尋ねたのとは異なる方法で望ましい結果を得るために:

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={() => this.removeTag(i)}なく、.bind


17
ただし、イベントオブジェクトは渡されません。
2015年

9
@chovy私が間違っている場合は修正してくださいが、すべてのJavaScript関数が本質的に可変であるとは限りませんか?私はこれをテストしていませんが、「イベントオブジェクト」がまだ渡されていると思います。以前と同じパラメータインデックスではありません。上で概説した方法でのバインドは、unshift関数の引数の配列を使用するようなものです。「イベントオブジェクト」がインデックス0にあった場合は、インデックスになりました1
Ryder Brooks

8
@chovy必要に応じてできます。Just doremoveTag: function(i, evt) {
Jared Forsyth 2015年

8
すっきりしていますが、多くのバインドを実行している場合、これらのバインドはすべてパフォーマンスに影響します。
エルヨボ2016


296

event.targetはネイティブDOMノードを提供し、その後、通常のDOM APIを使用して属性にアクセスする必要があります。これを行う方法に関するドキュメントを次に示しますデータ属性の使用

event.target.dataset.tagまたはのいずれかを実行できますevent.target.getAttribute('data-tag')。どちらでも機能します。


24
0.13.3の反応、IE10 event.target.datasetは未定義ですがevent.target.getAttribute('data-tag')動作します。他のブラウザは問題ありません。ありがとう
Andrey Borisko

このアプローチに問題はありますか?たとえば、ユーザーがどのボタンを押すかに応じて、文字列を関数に渡します。各ケースのコンポーネントで3つの関数を作成しないことを望んでいました。
マイケルJ.カルキンス2016

4
この回答は、パフォーマンスの点で、受け入れられている回答よりも優れています。このようにすることは、すべてのレンダリングで新しい関数を作成しないことを意味します。レンダリングのたびに新しい関数の作成をスキップするだけでなく、関数の参照は毎回同じであるため、純粋な(またはメモ化された)コンポーネントはそれを別の関数として認識しません。したがって、毎回コンポーネント全体が不必要に再レンダリングされることはありません。shouldComponentUpdate関数プロップを完全に無視しない限り、のカスタム実装でも同じ問題が発生します。
Michael Yaworski、

完全に問題なく動作する
Ogbonna Vitalis

1
私はtypescriptを使用しています。私の場合、使用しなければなりevent.currentTarget.getAttibute('data-tag')
ませんでした

50

これが私が見つけた最良の方法です:

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

これらの属性は「NamedNodeMap」に格納され、getNamedItemメソッドで簡単にアクセスできます。


4
あなたはおそらく.value実際の値を得るためにaを追加したいと思うでしょう
Wikunia '29

.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 2017

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 '29

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
「私」はどこから来たのですか?
Freshchris

2
iOPが何らかの方法で渡したいカスタム属性です。a要素が定義されたときにスコープ内にある変数です。
tytk

それはOPが望んでいることではありません。彼らはonClickハンドラーで要素(a)の属性値にアクセスしたいと考えています。
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私の作品




3

Reactについては知りませんが、一般的には次のようなカスタム属性を渡すことができます。

1)htmlタグ内にdata-接頭辞を持つ新しい属性を定義します

data-mydatafield = "asdasdasdaad"

2)JavaScriptから取得

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

鉱山はnullと言い続ける
Si8、19年

3

Reactでevent.targetを使用してnull値を見つけようとしているのは、SyntheticEventがevent.targetを置き換えたためです。SyntheticEventがevent.currentTarget.getAttribute( 'data-username')などの「currentTarget」を保持するようになりました。

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

Reactでは、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.