Reactでは、ユーザーの操作に応じてUIの動作を制御するために、イベントハンドリングが重要な役割を果たします。クリックやキーボード入力、フォーム送信など、さまざまなユーザーのアクションに対応するための方法を学び、インタラクティブなWebアプリケーションを作成しましょう。この記事では、Reactにおけるイベントハンドリングの基礎と、実際の使い方を解説します。
1. イベントハンドリングの基本
Reactでのイベントハンドリングは、HTMLに似ていますが、少し違いがあります。例えば、イベント名がキャメルケースで書かれている点や、イベントに渡す関数はJavaScriptの式として渡される点が挙げられます。
クリックイベントの例
// ButtonClick.tsx
function ButtonClick() {
function handleClick() {
alert("ボタンがクリックされました");
}
return <button onClick={handleClick}>クリック</button>;
}
export default ButtonClick; -
onClickは、HTMLのonclickに相当しますが、Reactではキャメルケースで記述します。 - イベントハンドラとして渡される
handleClick関数は、ユーザーがボタンをクリックした際に実行されます。
2. イベントハンドリングとthisの扱い
クラスコンポーネントを使用する場合、thisの扱いが重要です。通常、クラスコンポーネントのメソッド内でthisを使うと、thisはコンポーネントのインスタンスを指しますが、メソッドをイベントハンドラとして渡す際にはthisのバインドが必要です。
クラスコンポーネントでのthisのバインド
// Toggle.tsx
import React from "react";
interface ToggleState {
isOn: boolean;
}
class Toggle extends React.Component<{}, ToggleState> {
constructor(props: {}) {
super(props);
this.state = { isOn: true };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState((state) => ({
isOn: !state.isOn,
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isOn ? "ON" : "OFF"}
</button>
);
}
}
export default Toggle; - コンストラクタ内で
this.handleClick.bind(this)を使ってthisを正しくバインドします。 -
setStateを使って状態を切り替え、ボタンのラベルが「ON」か「OFF」に変わるようにしています。
アロー関数を使ったイベントハンドリング
関数コンポーネントやアロー関数を使う場合は、thisのバインドを明示的に行う必要がありません。アロー関数はthisを親スコープに自動的にバインドするため、コードがシンプルになります。
function Toggle() {
const [isOn, setIsOn] = React.useState(true);
return (
<button onClick={() => setIsOn(!isOn)}>
{isOn ? "ON" : "OFF"}
</button>
);
}
export default Toggle; 3. イベントオブジェクト
イベントハンドラに渡されるイベントオブジェクト(event)には、さまざまな情報が含まれています。例えば、クリック位置やキー入力の情報などを取得することが可能です。
イベントオブジェクトの例
// LogEvent.tsx
function LogEvent() {
function handleClick(event) {
console.log("クリック位置: ", event.clientX, event.clientY);
}
return <button onClick={handleClick}>クリックして位置を確認</button>;
}
export default LogEvent; -
event.clientXとevent.clientYを使うことで、ユーザーがクリックした位置を取得できます。
4. フォームイベントのハンドリング
フォームの入力や送信イベントを処理するのも、Reactのイベントハンドリングの基本的なタスクです。例えば、フォームに入力されたデータを管理し、送信時に処理を実行する方法を見ていきましょう。
フォーム入力の例
// Form.tsx
import React from "react";
function Form() {
const [name, setName] = React.useState<string>("");
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault(); // ページのリロードを防ぐ
alert(`送信された名前: ${name}`);
}
return (
<form onSubmit={handleSubmit}>
<label>
名前:
<input
type="text"
value={name}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setName(e.target.value)
}
/>
</label>
<button type="submit">送信</button>
</form>
);
}
export default Form; -
onChangeイベントでフォームの入力値が変更されるたびに状態を更新し、入力内容が即座に反映されるようにしています。 -
onSubmitイベントでフォームが送信された際に、デフォルトのページリロードを防ぎ、入力内容をアラートで表示します。
5. 条件付きレンダリングによる応用
イベントハンドリングと条件付きレンダリングを組み合わせることで、より複雑なUIを作成することができます。例えば、ボタンをクリックすると、コンテンツが表示されたり非表示になったりする機能を作成できます。
条件付きレンダリングの例
// ShowHide.tsx
import React from "react";
function ShowHide() {
const [isVisible, setIsVisible] = React.useState<boolean>(false);
return (
<div>
<button onClick={() => setIsVisible(!isVisible)}>
{isVisible ? "非表示にする" : "表示する"}
</button>
{isVisible && <p>このテキストは表示されます。</p>}
</div>
);
}
export default ShowHide; -
isVisibleという状態をトグルして、ボタンをクリックするとテキストが表示されたり非表示になったりします。
6. カスタムイベントハンドラ
Reactでは、独自のイベントハンドラを作成して、コンポーネント間でイベントを処理することも可能です。親コンポーネントから子コンポーネントにイベントハンドラを渡し、子コンポーネントで実行されるイベントを親コンポーネントが受け取る仕組みです。
親から子へのイベントハンドラの渡し方
// Parent.tsx
interface ChildProps {
onClick: (message: string) => void;
}
function Parent() {
function handleChildClick(message: string) {
alert(`子からのメッセージ: ${message}`);
}
return <Child onClick={handleChildClick} />;
}
function Child({ onClick }: ChildProps) {
return (
<button onClick={() => onClick("こんにちは!")}>
子コンポーネントのボタン
</button>
);
}
export default Parent; - 親コンポーネントの
Parentから子コンポーネントのChildにonClickプロパティとしてハンドラを渡します。 - 子コンポーネントのボタンがクリックされると、親コンポーネントの
handleChildClick関数が実行されます。
まとめ
Reactのイベントハンドリングは、インタラクティブなWebアプリケーションを作成するために欠かせない機能です。イベントオブジェクトを利用した基本的なクリックイベントや、フォームの入力処理、状態を管理してコンポーネントの表示を制御する方法など、Reactの基礎的なハンドリングを理解することで、より複雑なアプリケーション開発に役立ちます。イベントハンドリングはReactの柔軟性を引き出す強力なツールなので、ぜひ活用してみてください。

