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?

Zodでスキーマバリデーション

Last updated at Posted at 2024-08-18

Zodのファイルスキーマを作成

import { z } from "zod";

// PDFファイルの検証スキーマ
const schema = z.object({
  /** 名前 */
  nickname: z.string().min(1, { message: "名前を入力してください" }),
  /** 年齢 */
  age: z
    .number({ message: "年齢を半角数字で入力してください" })
    .int({ message: "年齢を整数で入力してください" })
    .gte(12, { message: "年齢を12歳以上で入力してください" }),
  /** メールアドレス */
  email: z.union([
    z
      .string()
      .email({ message: "メールアドレスの形式で入力してください" })
      .nullish(),
    z.literal(""),
  ]),
  /** JSONデータ */
  jsonData: z
    .string()
    .min(1, { message: "JSONデータを入力してください" })
    .refine((val) => {
      try {
        JSON.parse(val);
        return true;
      } catch {
        return false;
      }
    }, { message: "正しいJSON形式で入力してください" }),
  /** PDFファイル */
  pdfFile: z
    .any()
    .refine((file) => file instanceof File && file.type === "application/pdf", {
      message: "PDFファイルを選択してください",
    }),
});

React Hook Formとの統合

import { FC } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";

// スキーマから型を生成
type Inputs = z.infer<typeof schema>;

export const SchemaFormSample: FC = () => {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<Inputs>({
    mode: "onTouched",
    resolver: zodResolver(schema),
  });

  const onSubmit = (data: Inputs) => {
    // フォームの送信処理
    console.log("Validated data:", data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label>
          名前
          <input type="text" {...register("nickname")} />
        </label>
        {errors.nickname && <p>{errors.nickname.message}</p>}
      </div>
      <div>
        <label>
          年齢
          <input
            type="number"
            {...register("age", { valueAsNumber: true })}
          />
        </label>
        {errors.age && <p>{errors.age.message}</p>}
      </div>
      <div>
        <label>
          メールアドレス
          <input type="email" {...register("email")} />
        </label>
        {errors.email && <p>{errors.email.message}</p>}
      </div>
      <div>
        <label>
          JSONデータ
          <input type="text" {...register("jsonData")} />
        </label>
        {errors.jsonData && <p>{errors.jsonData.message}</p>}
      </div>
      <div>
        <label>
          PDFファイル
          <input type="file" {...register("pdfFile")} />
        </label>
        {errors.pdfFile && <p>{errors.pdfFile.message}</p>}
      </div>
      <div>
        <button type="submit">submit</button>
      </div>
    </form>
  );
};
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?