こんにちは!Reactの世界へようこそ。チーフアーキテクトの私です。
Reactを学び始めると、避けて通れないのが「Props(プロップス)」によるコンポーネント同士のデータのやり取りですよね。親から子へデータを渡すのはだんだん慣れてきたけれど、「ボタンがクリックされた時の関数(イベントハンドラ)」をPropsとして受け渡そうとした瞬間、TypeScriptの型定義でフリーズしてしまう……。そんな経験、ありませんか?
「一体どんな型を指定すればいいの? `Function`? それとも `any`?」
ネットで調べても、なんだか難解な記号のオンパレードで、そっとブラウザを閉じたくなる気持ち、痛いほどよく分かります。
大丈夫ですよ、安心してください。今回は、身近な「お買い物のレジ」の仕組みに例えながら、イベントハンドラPropsの型定義のモヤモヤをすっきり解消していきましょう!
—
1. イベントハンドラって、なに?(身近な例え話)
まずはイメージから。Reactのイベントハンドラ(`onClick`や`onChange`など)を、現実世界の「呼び出しボタン」や「インターホン」に例えてみましょう。
例えば、あなたが街の小さなお店で「カスタムオーダーのケーキ」を注文するとします。
お店のカウンターには、店員さんを呼ぶための「ピンポーンボタン」が置いてありますよね。
- ボタン(子コンポーネント): 実際にあなたが指でポチッと押すパーツ。
- 店員さんが駆けつけるアクション(イベントハンドラ): ボタンが押された時に、裏で何が起きるかの指示。
Reactでも全く同じです。
「ボタン」という見た目のパーツ(子)を作ったはいいものの、「実際に押された時に何をしてほしいか」の具体的な中身(親の持つ関数)は、ボタン自身は知りません。だから、親から「このボタンが押されたら、この関数を実行してね!」と、Props経由でイベントハンドラを受け取る必要があるんです。
—
2. つまずきがちなポイント:どんな型をつけたらいいの?
さて、ここでTypeScriptの出番です。
「このPropsとして受け取る関数は、クリックされた時に動くやつですよ」と、TypeScriptの先生に教えてあげる必要があります。
よくある初心者の失敗として、以下のように書いちゃうケースがあります。
// ❌ やりがちな例(ちょっともったいない書き方)
type ButtonProps = {
// すべての関数を受け入れちゃうガバガバな型
onClick: Function;
}
これだと、「どんな引数を受け取るどんな関数でもOK」になってしまい、TypeScriptの賢い補完やエラーチェックの恩恵をまったく受けられなくなってしまいます。
ここで登場するのが、React公式が用意してくれている専用の「イベントハンドラ型(`React.MouseEventHandler` など)」です。
—
3. 状況に応じた「正しい型」の選び方
Reactでは、イベントの種類(クリックなのか、文字入力なのか)によって、適切な型がきちんと用意されています。よく使う代表選手を3つに絞ってご紹介しますね。
① クリックイベントの場合:`React.MouseEventHandler`
ボタンやアイコンなど、「マウスでカチッとクリックする系」の王様です。
② 入力フォームの場合:`React.ChangeEventHandler`
`` や `
③ フォーム送信の場合:`React.FormEventHandler`
`

コメント