Reactイベント処理:関数プロップスの「カッコあり/なし」を完全マスター!
Reactのイベント処理でよく見かける「関数プロップスの渡し方」について、バッチリ分かるように解説します!
ボタンクリックやフォーム入力など、ユーザー操作に応じて処理を行う「イベント処理」。Reactでは、親コンポーネントから子コンポーネントに関数を渡して、これを実現します。その渡し方にはいくつかパターンがあって、特に ()
の有無で迷うことがありますよね。
// 1. カッコなし
<MyButton onClick={handleClick} />
// 2. カッコあり (アロー関数)
<MyButton onClick={() => handleClick()} />
<MyButton onClick={() => doSomethingWith(itemId)} />
<MyButton onClick={(e) => handleEventOnly(e)} />
<MyButton onClick={(value) => handleCustomData(value)} />
<MyButton onClick={(e) => processItem(item.id, e)} />
これらの違いと使い分けを、この記事でマスターしましょう!
イベントハンドラ
イベントハンドラは、「クリックされた」「入力された」みたいなイベント(出来事)が起きたときに処理(ハンドル)する関数のことです
()
なし) - 「レシピ」を渡す
パターン1:関数そのものを渡す (書き方: onClick={handleClick}
意味: handleClick
という関数そのもの(レシピ)を渡します。実行はしません。クリックされたときに、Reactやブラウザがこのレシピに従って実行します。
使う場面:
- イベントが起きたら単純に関数を実行したいとき。
- 親から特別な追加情報を渡す必要がないとき。
- 子コンポーネント(またはHTML要素)が渡してくる引数(通常はイベントオブジェクト
e
)だけで十分なとき。
() => ...
や (引数) => ...
)
パターン2:新しい「指示役」の関数を渡す (書き方: onClick={() => ...}
や onClick={(arg) => ...}
意味: 関数そのものではなく、「イベントが起きたら、この =>
の右側の処理を実行してね」という指示が書かれた、新しい小さな関数(指示役)を渡します。
なぜこれを使うの?
-
理由1:即時実行を防ぐため。
{handleClick()}
と書くと画面表示時に実行されてしまうのを防ぎます。 - 理由2:親から追加の情報を渡すため。
- 理由3:子から渡される引数を加工したり、使ったりするため。
() => handleClick()
)
パターン2-A: 引数なしで呼び出す (書き方: onClick={() => handleClick()}
意味: 指示役関数は、「イベントが起きたら、引数なしで handleClick()
を実行してね」と指示します。
() => handleClickWithArg(arg)
)
パターン2-B: 親から特定の引数を渡す (書き方: onClick={() => deleteItem(item.id)}
意味: 指示役関数は、「イベントが起きたら、親が知っている item.id
を引数として deleteItem
を実行してね」と指示します。非常によく使われます!
e
だけを使う ((e) => handleEventOnly(e)
)
パターン2-C: イベントオブジェクト 書き方: onClick={(e) => handleEventOnly(e)}
解説 (e
って何?):
-
onClick
のようなブラウザ標準のイベントでは、React(やブラウザ)が自動的にイベント情報を持つ「イベントオブジェクト」を作り、指示役関数(やハンドラ関数)の最初の引数として渡します。これをe
やevent
で受け取ります。 - このパターンは、「受け取った
e
をそのままhandleEventOnly
に渡してね」という意味です。
(argFromChild) => handleCustomData(argFromChild)
)
パターン2-D: 子コンポーネントから渡されるカスタム引数を使う (書き方: <CustomInput onChange={(value) => handleInputChange(value)} />
解説 (e 以外の引数?):
-
onClick
などの標準HTMLイベントはe
を渡しますが、自分で作ったコンポーネント(例:CustomInput
)の場合は、そのコンポーネントがどんな引数を渡すかを自由に決められます。 - 例えば、
CustomInput
コンポーネントが「値が変わったら、新しい値だけを引数としてonChange
プロップスを呼び出す」ように作られていたとします。 - その場合、親コンポーネントで
onChange
を受け取る指示役関数は、e
ではなく、CustomInput
から渡される「新しい値 (value
)」を引数として受け取ります。それが(value)
の部分です。 - そして
=>
の右側で、受け取ったvalue
を使って親のhandleInputChange
関数を呼び出しています。
使う場面:
- 自作コンポーネントなど、
e
以外の特定のデータ(入力値、選択された項目など)を子から受け取って処理したい場合。
e
またはカスタム引数)の両方を使う
パターン2-E: 親からの引数と子からの引数(書き方:
onClick={(e) => processItem(item.id, e)}
<CustomInput onChange={(value) => handleWithIdAndValue(item.id, value)} />
解説:
- 最も柔軟なパターンです。指示役関数は子から渡される引数(
e
またはvalue
など)を受け取ります。 - そして
=>
の右側で、本来の処理関数を呼び出す際に、親から渡したい引数 (item.id
など) と、子から受け取った引数 (e
やvalue
) の両方を渡します。
使う場面:
- 親が持つ情報と、子がイベント時に提供する情報の両方が必要な場合。
まとめ表:関数プロップスの渡し方
書き方 (例) | 渡しているもの | 親の関数が呼ばれるタイミング | 主な使い道 |
---|---|---|---|
{handler} |
関数そのもの (レシピ) | イベント発生時 | 単純なイベント通知。子からの引数(通常e )だけでOKな場合。 |
{() => handler()} |
新しい指示役関数 | イベント発生時 | 即時実行防止。追加引数なし。 |
{(e) => handler(e)} |
新しい指示役関数 | イベント発生時 | 標準イベントのイベントオブジェクト e を明示的に使いたい場合。 |
{() => handler(arg)} |
新しい指示役関数 | イベント発生時 | 親から子に追加の引数 arg を渡したい場合。(子からの引数は不要) |
{(argFromChild) => handler(argFromChild)} |
新しい指示役関数 | イベント発生時 | 自作コンポーネントなどから渡されるカスタム引数 argFromChild を使いたい場合。 |
{(e) => handler(arg, e)} |
新しい指示役関数 | イベント発生時 | 親からの引数 arg と標準イベントの e の両方を使いたい場合。 |
{(argFromChild) => handler(arg, argFromChild)} |
新しい指示役関数 | イベント発生時 | 親からの引数 arg と子からのカスタム引数 argFromChild の両方を使いたい場合。 |
ポイント:
-
{}
の中に直接関数名()
と書くと、レンダリング時に実行されるので注意! - イベント発生時に実行したい関数には
{handler}
(パターン1) を使うか、アロー関数でラップ{() => ...}
や{(arg) => ...}
(パターン2) する。 - 親から追加で引数を渡したい場合は、パターン2のアロー関数ラップが必須。
-
子から渡される引数(
e
やカスタム引数)を使いたい場合も、パターン2のアロー関数ラップが必要(引数を受け取るため)。
これで、関数プロップスの渡し方はバッチリですね! Reactでのイベント処理、楽しんでいきましょう!
Discussion