2
2

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-hook-form×yupでユーザー名の重複チェックを行う

Posted at

はじめに

現在TypeScript×Next.js×Rails APIでSNSアプリを作成しています。
ユーザー名の重複チェックをフロント側でできないだろうか、とググっていた時にreact-hook-form×yupで実装できるようなのでやってみました。

yupとは

バリデーションチェックのためのライブラリです。
スキーマを定義して、バリデーションのルールや表示するエラーメッセージを自由に設定・適用できます。

手順

入力値に対してバリデーションを実行するスキーマを定義し、バリデーションをカスタマイズしていきます。

react-hook-formとyupの統合にはResolverを使います。

これらを踏まえて作成したサンプルコードは下記です。
※入力項目は複数ありますが、ユーザー名の処理のみ抜粋

page.tsx
interface IFormInput {
  username: string;
}

// バリデーションスキーマを定義
const postSchema = yup.object().shape({
  username: yup
    .string()
    .required(`ユーザー名は必須です`)
    .test("sameusername", "ユーザー名が重複しています", async (input) => {
      const response = await getPosts();
      return !response.some((post: any) => post.username === input);
    }),
});

export default function Page() {

  const router = useRouter();
  const {
    register,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm<IFormInput>({
    resolver: yupResolver(postSchema), // yupを使ったバリデーションを設定
  });

  //(バックエンドとの連携部分)
  const postPostFunc = async (post: IFormInput) => {
    await postPost(post);
    if (router) {
      router.push("/posts");
    }
  };

  const onSubmit: SubmitHandler<IFormInput> = async (data) => {
    postPostFunc(data);
    reset();
  };

  return (
    <div>
      <h2 className="text-2xl font-bold text-indigo-800 dark:text-white mb-4">
        投稿作成
      </h2>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div>
          <label className="block mb-2 text-indigo-500">ユーザー名</label>
          <input
            className="w-full p-2 mb-2 text-indigo-700 border-b-2 border-indigo-500 outline-none focus:bg-gray-300"
            type="text"
            {...register("username")}
          />
          {errors.username && (
            <p className="text-red-500">{errors.username.message}</p>
          )}{" "}
        </div>

        <button
          className="w-full bg-indigo-700 hover:bg-pink-700 text-white font-bold py-2 px-4 mb-6 rounded"
          type="submit"
          disabled={Object.keys(errors).length > 0} // エラーがある場合は無効化
        >
          投稿
        </button>
      </form>
    </div>
  );
}

おわりに

今回yupの存在を初めて知りました。
最初はバックエンドでもバリデーションを実装して。。みたいな流れも考えていましたが、フロント側で完結できるのがありがたかったです。

参考

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?