Reactで複数イベントをまとめて処理!共通関数化でコード整理
生徒
「Reactでいろんなボタンや入力にそれぞれ別々のイベント処理を書いています。似た処理が多くて大変です。」
先生
「それなら、複数イベントを一つの関数にまとめて共通化すると便利です。」
生徒
「一つの関数にまとめるとどうなるんですか?」
先生
「ボタンや入力の種類が増えても、同じ処理を使い回せるのでコードが短くなり、管理もしやすくなります。」
生徒
「具体的な書き方を教えてください!」
先生
「では、複数のボタンイベントを一つの共通関数で処理する例を見てみましょう。」
1. 複数イベントを共通関数で処理する理由
Reactで画面を作っていくと、ボタンのクリックや入力欄の変更など、さまざまなイベント処理が登場します。最初は一つずつ処理を書いても問題ありませんが、同じような内容の処理が増えてくると、コードが長くなり「どこに何を書いたのか分かりにくい」状態になりがちです。
そこで役立つのが、複数のイベントを一つの共通関数にまとめて処理する考え方です。共通関数を使えば、処理の内容を一箇所に集約できるため、修正や追加も簡単になります。プログラミング未経験の方でも、「同じことを何度も書かない」という感覚で理解すると分かりやすいです。
import React, { useState } from "react";
function App() {
const [message, setMessage] = useState("こんにちは!");
const handleCommonClick = (label) => {
setMessage(label + "がクリックされました!");
};
return (
<div>
<p>{message}</p>
<button onClick={() => handleCommonClick("ボタンA")}>ボタンA</button>
<button onClick={() => handleCommonClick("ボタンB")}>ボタンB</button>
</div>
);
}
export default App;
このように、どのボタンが押されたかを引数で渡すだけで、同じ関数を使い回せます。イベントごとに関数を増やさずに済むため、コード全体がすっきりし、後から見直したときも理解しやすくなります。
2. 共通関数の基本例
共通関数の基本は、「どのイベントが起きたのか」を引数で渡して、関数の中で処理を分けることです。ボタンごとにhandleClickAやhandleClickBのような関数を量産しなくて済むため、React初心者でもコードの見通しが良くなります。特にボタンが増えていく画面では、共通関数があるだけで整理しやすくなります。
下の例では、クリックと入力のイベントをhandleEventという一つの関数に集めています。ポイントは、イベント発生時に「目印となる文字」を渡しているところです。これだけで、どのボタンが押されたか、入力があったかを同じ関数で判断できます。
import React, { useState } from "react";
function App() {
const [message, setMessage] = useState("");
const handleEvent = (eventType) => {
if (eventType === "clickA") {
setMessage("ボタンAがクリックされました!");
} else if (eventType === "clickB") {
setMessage("ボタンBがクリックされました!");
} else if (eventType === "input") {
setMessage("入力イベントが発生しました!");
}
};
return (
<div>
<h1>{message}</h1>
<button onClick={() => handleEvent("clickA")}>ボタンA</button>
<button onClick={() => handleEvent("clickB")}>ボタンB</button>
<input onChange={() => handleEvent("input")} placeholder="文字を入力" />
</div>
);
}
export default App;
もしボタンCを追加したくなった場合も、関数を新しく作るのではなく、handleEventの分岐を一つ増やすだけで対応できます。イベント処理が散らばらないので、後から見直すときも「ここを見れば全体が分かる」という状態を作りやすいです。
3. 共通関数化のメリット
このようにイベント処理を共通化すると、次のメリットがあります。
- 同じ処理を複数箇所で再利用できる
- コード量が減り、読みやすくなる
- イベント処理の追加や変更が一箇所で可能になる
- 親コンポーネントが整理され、UI構造が明確になる
特に、複数ボタンや入力欄があるフォームやダッシュボードの開発では、この共通関数化が役立ちます。
4. 共通関数に渡す値を工夫する
共通関数では、どのイベントが発生したかを判別するために引数で情報を渡すことが大切です。文字列だけでなく、オブジェクトやIDを渡すことで、より柔軟な処理が可能です。例えば、複数のフォーム入力を一つの関数で管理することもできます。
function App() {
const [formData, setFormData] = useState({ name: "", email: "" });
const handleInputChange = (field, value) => {
setFormData((prev) => ({ ...prev, [field]: value }));
};
return (
<div>
<input
placeholder="名前"
onChange={(e) => handleInputChange("name", e.target.value)}
/>
<input
placeholder="メール"
onChange={(e) => handleInputChange("email", e.target.value)}
/>
<p>名前: {formData.name}</p>
<p>メール: {formData.email}</p>
</div>
);
}
5. 共通関数化のポイント
複数イベントをまとめるときは次のポイントを意識しましょう。
- イベントごとに処理を分岐するロジックを明確にする
- 引数を工夫して柔軟に対応できるようにする
- UIコンポーネントと処理の関数を分離して可読性を高める
- 再利用性を意識して、共通関数を汎用的に設計する
これにより、Reactアプリの複雑なイベント管理も簡単に整理でき、開発効率を上げることができます。
6. 共通関数を使うときのよくある失敗例
共通関数は便利ですが、最初のうちは「とりあえず全部まとめてしまう」ことで、逆に分かりにくくなることもあります。特に初心者の方は、一つの関数に処理を詰め込みすぎてしまい、条件分岐が多くなりすぎるケースがよくあります。
共通関数はあくまで「似た役割のイベント」をまとめるためのものです。まったく性質の違う処理まで無理に一つにすると、後から見たときに理解しづらくなります。まずはクリック系、入力系など、役割が近いものから共通化する意識を持つと失敗しにくくなります。
7. 小さな画面から共通関数化を始めるコツ
共通関数化は、いきなり大きな画面や複雑な画面で取り入れる必要はありません。最初はボタンが2つ、3つ程度の小さな画面から試すのがおすすめです。動きが目で追いやすく、「共通化するとこうなるのか」という感覚をつかみやすくなります。
慣れてきたら、フォームや一覧画面など、イベントが増えやすい画面に広げていくと自然に身につきます。小さく始めて少しずつ応用していくことで、Reactのイベント処理全体の理解も深まります。
8. 共通関数化が活きる実践的な場面
実際のReact開発では、共通関数はさまざまな場面で活躍します。たとえば、管理画面の操作ボタン、設定画面の切り替え、フォームの入力チェックなど、同じ流れの処理が何度も登場する場面です。
共通関数を使ってイベント処理を整理しておくと、仕様変更やデザイン調整が入ったときも対応しやすくなります。コードの見通しが良い状態を保てるため、Reactでの開発を続けていくうえで大きな助けになります。
まとめ
Reactにおけるイベント処理の共通関数化は、コードの可読性とメンテナンス性を劇的に向上させる重要なテクニックです。 複数のボタンや入力フォームが存在するアプリケーションにおいて、個別にハンドラを作成するとコードが冗長になり、修正が必要になった際にすべての箇所を書き換えなければならないリスクが生じます。 しかし、イベントの種類や対象を引数として受け取る共通関数を導入することで、ロジックを一点に集約し、シンプルで美しいコンポーネント構造を保つことが可能になります。
実践的な実装例:複数フォームとボタンの統合管理
これまでの学習を踏まえ、より実戦に近いコードを書いてみましょう。
ここでは、複数の入力フィールドと複数のアクションボタンを、それぞれ一つの共通関数で管理する例を紹介します。
name属性を動的に利用することで、関数の引数を減らし、さらにスッキリとした記述が実現できます。
import React, { useState } from "react";
function MultiEventForm() {
const [state, setState] = useState({
userName: "",
userEmail: "",
statusMessage: "フォームを入力してください"
});
// 入力変更を一つの関数で一括処理
const handleChange = (e) => {
const { name, value } = e.target;
setState((prev) => ({
...prev,
[name]: value,
}));
};
// ボタンアクションを一つの関数で一括処理
const handleAction = (actionType) => {
switch (actionType) {
case "SAVE":
setState((prev) => ({ ...prev, statusMessage: "保存しました!" }));
break;
case "RESET":
setState({ userName: "", userEmail: "", statusMessage: "リセットしました" });
break;
case "CANCEL":
setState((prev) => ({ ...prev, statusMessage: "キャンセルされました" }));
break;
default:
break;
}
};
return (
<div className="container mt-4">
<div className="card p-4 shadow-sm">
<h4 className="mb-3">{state.statusMessage}</h4>
<div className="mb-3">
<label className="form-label">ユーザー名</label>
<input
type="text"
name="userName"
className="form-control"
value={state.userName}
onChange={handleChange}
/>
</div>
<div className="mb-3">
<label className="form-label">メールアドレス</label>
<input
type="email"
name="userEmail"
className="form-control"
value={state.userEmail}
onChange={handleChange}
/>
</div>
<div className="d-flex gap-2">
<button className="btn btn-primary" onClick={() => handleAction("SAVE")}>保存</button>
<button className="btn btn-secondary" onClick={() => handleAction("CANCEL")}>キャンセル</button>
<button className="btn btn-danger" onClick={() => handleAction("RESET")}>リセット</button>
</div>
<div className="mt-4 border-top pt-3">
<p>表示確認:{state.userName} ({state.userEmail})</p>
</div>
</div>
</div>
);
}
export default MultiEventForm;
Reactの hooks である useState と、JavaScript の computed property names(ブラケット記法)を組み合わせることで、
入力項目の数に依存しない柔軟なハンドラが作成できます。このように「型」が決まっている処理については積極的に共通化を検討しましょう。
ただし、ロジックが複雑になりすぎる場合は、無理に一つにまとめず、機能ごとに適切に分離することが、長期的な開発における「正解」への近道です。
生徒
「先生、共通関数の作り方がだいぶ分かってきました!入力フォームが増えても、name属性を使えば一つの関数で全部使い回せるんですね。これ、コードがすごく短くなって感動しました!」
先生
「その通りです。特に React では状態(State)の更新パターンが決まっていることが多いので、共通化の恩恵は大きいんですよ。でも、逆に使いにくくなったと感じることはありませんか?」
生徒
「うーん、実はさっき、クリックしたときに『データを保存する処理』と『画面の色を変える処理』を一つの関数にまとめようとしたら、if文が複雑になってしまって……。」
先生
「それは良い気づきですね。何でもかんでも一つの関数に詰め込めばいいというわけではありません。共通化の基準は『目的が同じかどうか』です。データの更新という同じ目的であればまとめ、全く別の役割を持つ処理なら、無理にまとめずに関数を分ける方が、あとで不具合を探すときに楽になりますよ。」
生徒
「なるほど!『似ている処理』をまとめるのではなく、『同じ種類の役割』をまとめるのがコツなんですね。今回のコードでも handleChange は入力用、handleAction はボタン操作用と分けているから読みやすいんだと納得しました。」
先生
「完璧な理解です!そのバランス感覚が身につくと、エンジニアとしてのスキルが一気に上がります。次は、この共通関数をさらに別のファイルに切り出して、再利用可能な『カスタムフック』にする方法にも挑戦してみましょうか。」
生徒
「カスタムフック!どんどん本格的になってきましたね。もっと効率的な書き方をマスターしたいので、ぜひ教えてください!」
先生
「よし、その意気です。React の世界は学べば学ぶほど開発が楽に、楽しくなります。一歩ずつ、綺麗なコードを目指して頑張っていきましょう!」