0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React】検証バリデートライブラリ「Yup」を使ってみる

Posted at

今回は、検証ライブラリ「Yup」を使ったバリデータ尾を実装してみます。

image.png

未入力のままだと、下記のようなエラーが出ます。
image.png

また、メールアドレスがフォーマット異常だと下記のようなエラーになります。
image.png

ソース

UserForm.tsx
import React from "react";
import { useAppSelector, useAppDispatch } from "@/app/hooks";
import { setName, setEmail, resetUser } from "./userSlice";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { useForm } from "react-hook-form";

const schema = yup.object({
  name: yup.string().required("名前は入力必須です。").trim().min(1, "空白のみは不可です。"),
  email: yup
    .string()
    .required("メールアドレスは入力必須です。")
    .email("メールアドレスの形式が正しくありません。"),
});

type FormValues = {
  name: string;
  email: string;
};

export const UserForm: React.FC = () => {
  const dispatch = useAppDispatch();
  const { name, email } = useAppSelector((state) => state.user);

  const {
    register,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm<FormValues>({
    resolver: yupResolver(schema),
    defaultValues: { name, email },
  });

  const onSubmit = (data: FormValues) => {
    dispatch(setName(data.name));
    dispatch(setEmail(data.email));
    alert(`送信しました:\n名前: ${data.name}\nメール: ${data.email}`);
  };

    // ✅ リセットボタン処理
  const handleReset = () => {
    reset({ name: "", email: "" }); // ← フォームの値をクリア
    dispatch(resetUser());          // ← Redux の状態も初期化
  };

  return (
    <form
      onSubmit={handleSubmit(onSubmit)}
      style={{ maxWidth: 400, margin: "2rem auto" }}
      className="border border-gray-500 rounded px-4 py-4"
    >
      <h2>ユーザー情報フォーム</h2>

      <div style={{ marginBottom: "1rem" }}>
        <label>名前:</label>
        <input
          type="text"
          {...register("name")}
          style={{ width: "100%", padding: "0.5rem" }}
          className="border border-gray-500 rounded px-4 py-4"
        />
        {errors.name && (
          <p style={{ color: "red", fontSize: "0.9rem" }}>{errors.name.message}</p>
        )}
      </div>

      <div style={{ marginBottom: "1rem" }}>
        <label>メール:</label>
        <input
          type="email"
          {...register("email")}
          style={{ width: "100%", padding: "0.5rem" }}
          className="border border-gray-500 rounded px-4 py-4"
        />
        {errors.email && (
          <p style={{ color: "red", fontSize: "0.9rem" }}>{errors.email.message}</p>
        )}
      </div>

      <button
        type="submit"
        className="bg-blue-500 rounded text-white font-bold px-4 py-4 mr-4 hover:bg-blue-700 cursor-pointer"
      >
        送信
      </button>

      <button
        type="button"
        onClick={(handleReset)}
        className="bg-gray-500 rounded text-white font-bold px-4 py-4 mr-4 hover:bg-gray-700 cursor-pointer"
      >
        リセット
      </button>
    </form>
  );
};

react-hook-form にはreset()という関数があり、フォーム全体を初期化(または指定した値にリセット)できます。
Redux resetUser()も呼び出したいので、両方を組み合わせましょう。

サイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?