イベントオブジェクト
ハンドラは情報を受け取れる
イベントハンドラは、呼ばれるときに引数を 1 つ受け取ります。何が起きたのかをまとめた イベントオブジェクト です。慣習として e または event という名前を付けます。
function handleClick(e) {
console.log(e.type); // "click"
console.log(e.target); // 実際に押された要素
}渡すのは自分ではありません。onClick={handleClick} と関数を渡しておけば、React が押されたときに e を入れて呼んでくれます。
e.target は「押された当人」
一番よく使うのが e.target です。イベントが起きた要素そのものを指します。要素なので、そこから属性も中身も読めます。
function handleClick(e) {
console.log(e.target.textContent); // ボタンの文字
console.log(e.target.dataset.id); // data-id の値
}data- で始まる属性は、HTML が自由に付けてよい印です。JSX でもそのまま data-id="1" と書けて、JavaScript 側では e.target.dataset.id で取り出せます。「どのボタンが押されたか」を区別したいときの定番です。
3 つのボタンに 1 つのハンドラ
ボタンごとに別々の関数を用意すると、ボタンが増えるたびに関数も増えます。data 属性とイベントオブジェクトを使えば、ハンドラは 1 つで足ります。
function handleSelect(e) {
setSelected(e.target.dataset.title);
}
<button data-title="レシピ検索アプリ" onClick={handleSelect}>レシピ検索アプリ</button>
<button data-title="買い物メモツール" onClick={handleSelect}>買い物メモツール</button>どちらを押しても同じ関数が呼ばれますが、e.target が違うので結果が変わります。
target と currentTarget
似たものに e.currentTarget があります。target が「実際に押された一番内側の要素」なのに対し、currentTarget は「ハンドラを付けた要素」です。ボタンの中に span を入れて span を押すと、target は span、currentTarget はボタンになります。data 属性をボタンに付けているのに値が取れないときは、たいていこれが原因です。中に要素を入れるなら currentTarget を使ってください。
演習
作品名のボタンを押すと、選択中の作品名が変わるようにします。