Reactでフォーム送信イベント(onSubmit)の使い方を初心者向けに解説
生徒
「Reactでフォームを送信したときに処理をしたいです。どうすればいいですか?」
先生
「その場合は、onSubmitイベントを使います。フォームが送信されたときに呼ばれる関数を設定します。」
生徒
「送信ボタンを押したときのページのリロードは防げますか?」
先生
「はい、event.preventDefault()を使うとページのリロードを防ぎつつ、送信処理を実行できます。」
生徒
「それでは、具体的なコードを見てみたいです!」
1. フォーム送信イベントの基本
Reactでは、フォームの送信イベントを扱うときにonSubmit属性を使います。通常のHTMLフォームでは、送信ボタンを押すとページがリロードされますが、ReactではpreventDefault()を使ってリロードを防ぎ、必要な処理だけ実行します。
import React, { useState } from "react";
function App() {
const [name, setName] = useState("");
const handleSubmit = (event) => {
event.preventDefault(); // ページのリロードを防ぐ
alert("送信された名前: " + name);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="名前を入力"
/>
<button type="submit">送信</button>
</form>
);
}
export default App;
onChangeイベントで入力値をuseStateで管理し、onSubmitで送信処理を行うのがReactでの基本パターンです。
2. 複数入力フィールドの場合の送信処理
フォームに複数の入力フィールドがある場合も、onSubmitでまとめて処理できます。オブジェクトで状態を管理すると便利です。
import React, { useState } from "react";
function App() {
const [formData, setFormData] = useState({ name: "", email: "" });
const handleChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const handleSubmit = (e) => {
e.preventDefault();
alert("名前: " + formData.name + ", メール: " + formData.email);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
placeholder="名前"
/>
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
placeholder="メール"
/>
<button type="submit">送信</button>
</form>
);
}
export default App;
このようにonChangeで各入力を状態に反映させ、onSubmitでまとめて処理することで、フォーム送信のロジックをわかりやすく整理できます。
3. 実践的なポイント
フォーム送信イベントでは、必ずevent.preventDefault()を使ってページリロードを防ぐことが重要です。また、入力値をuseStateで管理することで、送信前に値をチェックしたり、バリデーションを行ったりすることが簡単になります。
フォームの入力フィールドが増えても、状態をオブジェクトでまとめて管理するとコードがシンプルになり、メンテナンスしやすくなります。ReactのonSubmitイベントは、ユーザーの操作に応じた動的な処理を実装するのに欠かせない基本機能です。
4. 入力バリデーションとエラーメッセージの表示方法
Reactでフォーム送信を扱う際には、入力値のバリデーションを実装しておくと、正しい情報を送信したい場合にとても役立ちます。ユーザーが名前やメールの入力を誤ったまま送信しようとしたとき、即座にエラーを表示することで、間違いに気づきやすくなり、正しいデータ入力を促すことができます。
バリデーションには、onSubmit内で入力内容をチェックしたり、onChangeで入力のたびにチェックする方法があります。Reactの状態管理機能と組み合わせることで、入力が正しくない場合にメッセージを表示したり、送信ボタンを無効化したりする仕組みも簡単に実装できます。
import React, { useState } from "react";
function ValidationForm() {
const [name, setName] = useState("");
const [error, setError] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
if (name === "") {
setError("名前を入力してください");
return;
}
setError("");
alert("送信された名前: " + name);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="名前"
/>
{error && <div style={{ color: "red" }}>{error}</div>}
<button type="submit">送信</button>
</form>
);
}
export default ValidationForm;
このように簡単な条件分岐を加えるだけで動的なバリデーションが行えるため、フォームの品質を大きく向上させることができます。
5. フォーム送信後の状態リセット方法
フォームを送信したあと、入力値をリセットして画面を初期状態に戻したいことがあります。ユーザーが続けて入力を行うケースでは、送信後にフォームをクリアすることで操作性を高められます。ReactのuseStateで管理している入力値を再び空文字に戻すだけで簡単にリセットできます。
入力フィールドが複数ある場合でも、状態オブジェクトを初期値に戻すことで一括リセットできます。次の例は送信後にフォーム内容をクリアする流れを示しています。
import React, { useState } from "react";
function ResetForm() {
const [form, setForm] = useState({ name: "", email: "" });
const handleSubmit = (e) => {
e.preventDefault();
alert("送信完了: " + form.name + " / " + form.email);
setForm({ name: "", email: "" }); // 状態リセット
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="name"
value={form.name}
placeholder="名前"
onChange={(e) => setForm({ ...form, name: e.target.value })}
/>
<input
type="email"
name="email"
value={form.email}
placeholder="メール"
onChange={(e) => setForm({ ...form, email: e.target.value })}
/>
<button type="submit">送信</button>
</form>
);
}
export default ResetForm;
フォームリセットはシンプルですが、使う場面が多いため覚えておくと便利です。
6. サーバー通信と非同期処理を組み合わせた送信方法
実際のアプリケーションでは、フォームで入力されたデータをサーバーへ送信することが多くあります。その際にはfetchやaxiosなどを使って非同期処理を実装します。onSubmit内で非同期関数を実行することで、送信内容をバックエンドに送ったり、APIからレスポンスを受け取ったりできます。
非同期処理を行うときは、送信中にボタンを押せないようにしたり、ロード中の表示を出したりして、ユーザーが状況を把握できるようにすることが重要です。次の例は簡単なサーバー送信の流れを示しています。
import React, { useState } from "react";
function AsyncSubmitForm() {
const [name, setName] = useState("");
const [loading, setLoading] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
const response = await fetch("/api/send", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name })
});
setLoading(false);
if (response.ok) {
alert("送信成功: " + name);
setName("");
} else {
alert("送信に失敗しました");
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={name}
placeholder="名前"
onChange={(e) => setName(e.target.value)}
/>
<button type="submit" disabled={loading}>
{loading ? "送信中..." : "送信"}
</button>
</form>
);
}
export default AsyncSubmitForm;
非同期処理を正しく組み込むことで、現実的なアプリケーションに対応できる送信フォームを作成できます。
まとめ
Reactでフォーム送信を扱うときに理解しておくべき基礎として、onSubmitイベントの仕組みやpreventDefaultによるページリロード防止、そしてuseStateによる入力値の管理が大切であることがわかった。フォームはウェブアプリケーションの中でも特に多く使われる機能であり、入力内容をそのまま送信するだけでなく、送信前に確認したり、バリデーションを実行したり、入力内容を他のコンポーネントに渡したりと、さまざまな役割を持つ。こうした流れをReactで実装するとき、onSubmitを正しく使うことが重要になる。特にpreventDefaultを用いることで、通常のHTMLフォームのようにページが切り替わってしまう動きを避け、アプリとして自然なユーザー体験を作り出せる。
また、ひとつの入力フィールドだけではなく、複数の入力を扱う場面は非常に多く、名前やメールアドレスに加えて住所や年齢など、管理すべき値が増えることは珍しくない。そのような場合には、formDataのようなオブジェクトで状態をまとめて扱う方法が役立つ。入力項目が増えてもコードが散らからず、メンテナンス性も向上し、可読性の高いフォーム送信処理となる。Reactの特性上、状態を管理しながらUIを更新していくため、各フィールドの変更をonChangeで確実に拾いつつ、onSubmitによって送信処理をひとつの流れとしてまとめることができる。このしくみを理解すると、より複雑なフォームも無理なく作りこむことができるようになる。
さらに、送信イベントの中でバリデーションを行うことも多く、入力が空であればエラーメッセージを表示したり、形式が正しくない場合に警告を出したりと、ユーザーにとって使いやすいフォームを作るための工夫が求められる。Reactでは状態を更新するだけで画面が即座に変わるため、エラーの可視化や確認メッセージの表示なども簡単に実装できる。こうした点が動的なフォーム開発の大きな強みである。送信前に入力の確認が必要な場合や、入力内容を他の関数に渡す必要がある場合、onSubmitでロジックを整理することで迷わず扱えるようになる。
サンプルプログラムで振り返り
import React, { useState } from "react";
function ReviewForm() {
const [form, setForm] = useState({ name: "", email: "", message: "" });
const handleChange = (e) => {
setForm({ ...form, [e.target.name]: e.target.value });
};
const handleSubmit = (e) => {
e.preventDefault();
alert("入力内容: " + form.name + " / " + form.email + " / " + form.message);
};
return (
<form onSubmit={handleSubmit} className="review-form">
<input
type="text"
name="name"
placeholder="おなまえ"
value={form.name}
onChange={handleChange}
/>
<input
type="email"
name="email"
placeholder="めーるあどれす"
value={form.email}
onChange={handleChange}
/>
<textarea
name="message"
placeholder="めっせーじ"
value={form.message}
onChange={handleChange}
/>
<button type="submit">送信</button>
</form>
);
}
export default ReviewForm;
このサンプルでは、名前・メール・メッセージの三つをまとめて管理し、送信時にすべてを確認する処理を実装している。複数項目を扱うときでもonChangeとonSubmitを組み合わせるだけで、自然なフォーム送信の流れが作れることがわかる。どの入力がどの状態に対応するのか明確であり、ユーザーが入力していくたびに画面が変化し、送信時には必要なデータがすべてそろっている。このようなフォームは日常的に利用されるため、丁寧に設計すればUIの完成度が大きく高まる。
生徒:「ReactのonSubmitが思っていたより使いやすいことに気づきました。preventDefaultの役割もはっきりわかりました。」
先生:「そうですね。送信処理の基本はリロードを防ぐことから始まります。それをしないと、Reactの良さが生かせません。」
生徒:「複数フィールドをまとめて扱う方法も理解できました。状態をひとつにまとめると整理しやすいんですね。」
先生:「その通りです。入力項目が増えるほど、オブジェクト管理が便利になりますよ。」
生徒:「送信の前に確認メッセージを出したり、条件によってエラーを表示したりするのも簡単にできそうです。」
先生:「Reactでは画面更新が自然に行われるので、バリデーションの表現も工夫しやすいです。今回の学びをしっかり生かしてくださいね。」