✅
Next.jsのselect要素のバリデーション
select要素のバリデーションとは
ブラウザのコンソールでユーザーがoptionタグののvalueをいじってフォーム送信すると、意図した選択肢以外の値が送られてきてしまいます。
これを防ぐために、別ファイルであらかじめ選択肢を配列で羅列しておき、それをもとにArray.includes()関数でチェックします。
手順
- 別ファイルに選択肢を羅列した配列を作る。
- Array.includes()関数で、あらかじめ作成した配列に含まれているかチェック
↓react-hook-formを使わない場合
// 1. 別ファイルに選択肢を羅列した配列を作る。
// options.js
export const validCategories = [
"tech", // 技術
"design", // デザイン
"marketing" // マーケティング
];
// 2. Array.includes()関数で、あらかじめ作成した配列に含まれているかチェック
// MyForm.tsx
import React, { useState } from "react";
import { validCategories } from "./options"; // 選択肢をインポート
const MyForm = () => {
const [category, setCategory] = useState<string>("");
const [error, setError] = useState<string>("");
// フォーム送信時の処理
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// 選択肢が無効な場合はエラー
if (!validCategories.includes(category)) {
setError("無効なカテゴリが選択されました。正しいカテゴリを選択してください。");
return; // フォーム送信を中止
}
// エラーがなければ送信処理を実行
setError("");
console.log("フォーム送信データ:", { category });
// ここでデータ送信処理を行う
};
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="category">カテゴリ</label>
<select
id="category"
value={category}
onChange={(e) => setCategory(e.target.value)}
>
// valueの値が選択肢と同じときは、map関数で展開してもいいですね。
<option value="">選択してください</option>
<option value="tech">技術</option>
<option value="design">デザイン</option>
<option value="marketing">マーケティング</option>
</select>
{/* エラーメッセージ */}
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
<button type="submit">送信</button>
</form>
);
};
export default MyForm;
↓react-hook-formを使った場合
// 1. 別ファイルに選択肢を羅列した配列を作る。
// options.js
export const validCategories = [
"tech", // 技術
"design", // デザイン
"marketing" // マーケティング
];
// 2. Array.includes()関数で、あらかじめ作成した配列に含まれているかチェック
// MyForm.tsx
import React from "react";
import { useForm } from "react-hook-form"; // react-hook-form をインポート
import { validCategories } from "./options"; // 選択肢をインポート
type FormData = {
category: string;
};
const MyForm = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<FormData>(); // useForm を使ってフォームを管理
// フォーム送信時の処理
const onSubmit = (data: FormData) => {
console.log("フォーム送信データ:", data);
// バリデーションチェック
if (!validCategories.includes(data.category)) {
alert("無効なカテゴリが選択されました。");
return;
}
// 正常な場合は送信処理を行う
alert("送信成功!");
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="category">カテゴリ</label>
<select
id="category"
{...register("category", {
required: "カテゴリを選択してください",
validate: (value) => validCategories.includes(value) || "無効なカテゴリです",
})}
>
// valueの値が選択肢と同じときは、map関数で展開してもいいですね。
<option value="">選択してください</option>
<option value="tech">技術</option>
<option value="design">デザイン</option>
<option value="marketing">マーケティング</option>
</select>
{/* エラーメッセージ */}
{errors.category && <p style={{ color: "red" }}>{errors.category.message}</p>}
</div>
<button type="submit">送信</button>
</form>
);
};
export default MyForm;
Discussion