たろ
ReactでHTMLの属性ってどうやって取得するの?
こんな疑問にお答えします。
本記事の内容
- Reactで属性取得は target また currentTarget を使う
- currentTarget を使う方をお勧めする←記事の中で解説
- target と currentTarget はReactの関数ではなくWeb API
こんにちは。
React(JavaScript) の実装中 target と currentTarget の違いでハマったので戒めとしてメモを残しておきます。
HTML に書かれた DOM の属性を取得するコードを書いていたときに思うようにコードが動かず数時間デバッグに費やしたのでいい思い出です。(泣)
target と currentTarget の違い
例えば、以下のようなサンプルコードがあるとします。
function App() {
const onClick = (e) => {
console.log(e.target);
console.log(e.currentTarget);
};
return (
<button onClick={onClick}>
<strong>Click me</strong>
</button>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
一見、クリックイベント発火後、同じ結果コンソールに出力してくれるように見えますが、全く違う結果になります。
console.log(e.target); // <strong>Click me</strong>
console.log(e.currentTarget); // <button>...</button>
それぞれ上のような出力になります。
なぜこのような結果になるというと、こちらでも記載がある通り
target
:イベントを呼び出した要素を参照currentTarget
:イベントハンドラーをアタッチした要素を参照
となるためです。
他にも調べてみるとバグを防ぐためにも currentTarget を利用することを推奨する記事が多く見受けられました。
いずれにせよ、両方の違いをきちんと理解し適切な実装を心がけたいと思った事例でした。
ReactでHTMLの属性を取得
クリックイベントをトリガーにし各属性を取得してみることにします。
- id
- name
- data
例えば上のようなよく使う3つの属性を値を取得するコードは次のようになります。
function App() {
const onClick = (e) => {
console.log(e.currentTarget);
console.log(e.target);
console.log(e.currentTarget.id);
console.log(e.currentTarget.name);
console.log(e.currentTarget.dataset.btn);
console.log(e.target.dataset.str);
};
return (
<button id="i-am-btn" name="my-name-is-btn" data-btn="data-button" onClick={onClick}>
<strong data-str="string">Click me</strong>
</button>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
結果はこちら↓
console.log(e.currentTarget); // <button id="i-am-btn" name="my-name-is-btn" data-btn="data-button" onClick={onClick}>
// <strong data-str="string">Click me</strong>
// </button>
console.log(e.target); // <strong data-str="string">Click me</strong>
console.log(e.currentTarget.id); // i-am-btn
console.log(e.currentTarget.name); // my-name-is-btn
console.log(e.currentTarget.dataset.btn); // data-button
console.log(e.target.dataset.str); // string
まとめ
以上、ReactでHTMLの属性を取得する方法でした。
HTMLの構造次第では currentTarget を使うと子要素にもアクセスできるようなので currentTarget を使うように心がけます。
検証
紹介したコードを試すボタンを用意してみました。
開発ツールを開き下記のボタンをクリックしてみてください。
コメント