フロントエンド開発といえば。
react アプリの初期化( npm init vite@latest <アプリ名> )

React Hook Form + zod

● React Hook Form + zod のインストール

npm install react-hook-form zod
npm install @hookform/resolvers

● React Hook Form + zod のコンポーネントサンプル

・1. バリデーションの定義を別ファイルにします

src/validations/mysourceCreateSchema.ts

import { z } from "zod";

export const mysourceCreateSchema = z.object({
  source: z.string().nonempty("翻訳したい文章を入力してください"),
  answer: z.string().nullish(),
});

export type MysourceCreateSchema = z.infer<typeof mysourceCreateSchema>;

・2. コンポーネントから呼び出します

import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from "@hookform/resolvers/zod";
import { MysourceCreateSchema, mysourceCreateSchema } from "@/validations/mysourceCreateSchema";

const MyForm: React.FC<Props> = ({ onSubmit }) => {
  // react-hook-form
  const { register, formState, handleSubmit } = useForm<MysourceCreateSchema>({
    resolver: zodResolver(mysourceCreateSchema)
  });
  const { errors } = formState;

  const onSubmit: SubmitHandler<MysourceCreateSchema> = (data) => {
    console.log("● data");
    console.log(data);
  };

  return (
    {/* noValidate: htmlのバリデーション機能をオフにする */}
    <form noValidate onSubmit={handleSubmit(handleFormSubmit)}>
      <div>
        <label htmlFor="source">Source</label>
        <input {...register("source")} type="text" />
        {errors.source && <span>{errors.source.message}</span>}
      </div>
      <div>
        <label htmlFor="answer">Answer</label>
        <input {...register("answer")} type="text" />
        {errors.answer && <span>{errors.answer.message}</span>}
      </div>
      <button type="submit" disabled={submitting}>Submit</button>
    </form>
  );
};

● Zodライブラリの型定義

Zodは、TypeScriptで使用するためのスキーマ検証ライブラリです。 このライブラリは、入力値の型を厳密にチェックし、型安全性を向上させます。

Zodライブラリには、次の型定義が含まれています。

z.array:配列の要素に対する型を定義する
z.nullable:nullまたは指定された型の値を許容する
z.optional:undefinedまたは指定された型の値を許容する
z.nullish:nullまたはundefinedの値を許容する

z.literal:特定の値のリテラルを指定する
引数に渡せる値は string | number | bigint | boolean | null | undefined のみとなっています。

z.union:複数の型を許容する
z.nonempty:空ではない配列または文字列を許容する
z.any:任意の値を許容する
z.unknown:不明な値を許容する

これらの型定義は、TypeScriptの型を厳密に制限することで、プログラムの信頼性を高めることができます。

● FieldWrapper を作成してエラーの表示をまとめる

参考 : https://github.com/alan2207/bulletproof-react/blob/master/src/components/Form/FieldWrapper.tsx

import * as React from "react";
import { FieldError } from "react-hook-form";

type FieldWrapperProps = {
  children: React.ReactNode;
  error?: FieldError | undefined;
};

export type FieldWrapperPassThroughProps = Omit<
  FieldWrapperProps,
  "className" | "children"
>;

export const FieldWrapper = (props: FieldWrapperProps) => {
  const { error, children } = props;
  return (
    <>
      {children}
      {error?.message && <div className={"error_input"}>{error.message}</div>}
    </>
  );
};

使い方

<FieldWrapper error={errors.source}>
  <TextField
    {...register("source")}
    multiline={true}
    variant="outlined"
    fullWidth={true}
    placeholder="翻訳したい文章を入力します"
  />
</FieldWrapper>
No.2336
02/05 11:54

edit