Use Cases

Claude Code के साथ React Hook Form

Claude Code का उपयोग करके react hook form सीखें। Practical tips और code examples शामिल हैं।

React Hook Formでハイperformanceなform buildする

React Hook Formは非制御componentベースのformlibraryで、レンダリング回数を最小限に抑えたfastなform build किया जा सकता है。Claude Code का उपयोग करके、complexなform設計も素早くimplementationpossible है।

basic form構成

Claude Codeにform全体の設計を依頼 करें।

> React Hook FormとZodで問い合わせformをबनाओ。
> 名पहले、メール、カテゴリ選択、本文を含めて。errordisplayもつけて。
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";

const contactSchema = z.object({
  name: z.string().min(1, "お名पहलेを入力してください"),
  email: z.string().email("有効なメールアドレスを入力してください"),
  category: z.enum(["general", "support", "billing", "other"], {
    errorMap: () => ({ message: "カテゴリを選択してください" }),
  }),
  message: z
    .string()
    .min(10, "本文は10文字以ऊपरで入力してください")
    .max(2000, "本文は2000文字以内で入力してください"),
});

type ContactFormData = z.infer<typeof contactSchema>;

function ContactForm() {
  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitting },
    reset,
  } = useForm<ContactFormData>({
    resolver: zodResolver(contactSchema),
    defaultValues: {
      category: undefined,
    },
  });

  const onSubmit = async (data: ContactFormData) => {
    await sendContactForm(data);
    reset();
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label htmlFor="name">お名पहले</label>
        <input id="name" {...register("name")} />
        {errors.name && <p role="alert">{errors.name.message}</p>}
      </div>

      <div>
        <label htmlFor="email">メールアドレス</label>
        <input id="email" type="email" {...register("email")} />
        {errors.email && <p role="alert">{errors.email.message}</p>}
      </div>

      <div>
        <label htmlFor="category">カテゴリ</label>
        <select id="category" {...register("category")}>
          <option value="">選択してください</option>
          <option value="general">一般</option>
          <option value="support">サポート</option>
          <option value="billing">請求</option>
          <option value="other">उस他</option>
        </select>
        {errors.category && <p role="alert">{errors.category.message}</p>}
      </div>

      <div>
        <label htmlFor="message">本文</label>
        <textarea id="message" rows={5} {...register("message")} />
        {errors.message && <p role="alert">{errors.message.message}</p>}
      </div>

      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? "送信में..." : "送信"}
      </button>
    </form>
  );
}

動的field(useFieldArray)

可variableのfieldをmanagementするpattern है।

import { useForm, useFieldArray } from "react-hook-form";

interface InvoiceForm {
  clientName: string;
  items: {
    description: string;
    quantity: number;
    unitPrice: number;
  }[];
  notes: string;
}

function InvoiceForm() {
  const { register, control, handleSubmit, watch } = useForm<InvoiceForm>({
    defaultValues: {
      items: [{ description: "", quantity: 1, unitPrice: 0 }],
    },
  });

  const { fields, append, remove } = useFieldArray({
    control,
    name: "items",
  });

  const watchItems = watch("items");
  const total = watchItems.reduce(
    (sum, item) => sum + (item.quantity || 0) * (item.unitPrice || 0),
    0
  );

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("clientName")} placeholder="client名" />

      {fields.map((field, index) => (
        <div key={field.id}>
          <input
            {...register(`items.${index}.description`)}
            placeholder="品目"
          />
          <input
            type="number"
            {...register(`items.${index}.quantity`, { valueAsNumber: true })}
          />
          <input
            type="number"
            {...register(`items.${index}.unitPrice`, { valueAsNumber: true })}
          />
          <button type="button" onClick={() => remove(index)}>
            delete
          </button>
        </div>
      ))}

      <button
        type="button"
        onClick={() => append({ description: "", quantity: 1, unitPrice: 0 })}
      >
        品目をadd
      </button>

      <p>合計: ¥{total.toLocaleString()}</p>
      <button type="submit">保存</button>
    </form>
  );
}

マルチステップform

ウィザード形式のformもClaude Code सेefficientlyimplementationでき है।

import { useForm, FormProvider, useFormContext } from "react-hook-form";

interface MultiStepFormData {
  // Step 1
  firstName: string;
  lastName: string;
  email: string;
  // Step 2
  company: string;
  role: string;
  // Step 3
  plan: "free" | "pro" | "enterprise";
  agreeToTerms: boolean;
}

function MultiStepForm() {
  const [step, setStep] = useState(1);
  const methods = useForm<MultiStepFormData>({
    mode: "onChange",
  });

  const next = async () => {
    const fieldsToValidate = getFieldsByStep(step);
    const isValid = await methods.trigger(fieldsToValidate);
    if (isValid) setStep((s) => s + 1);
  };

  const prev = () => setStep((s) => s - 1);

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        {step === 1 && <PersonalInfoStep />}
        {step === 2 && <CompanyInfoStep />}
        {step === 3 && <PlanSelectionStep />}

        <div>
          {step > 1 && <button type="button" onClick={prev}>戻る</button>}
          {step < 3 ? (
            <button type="button" onClick={next}>अगलाへ</button>
          ) : (
            <button type="submit">完了</button>
          )}
        </div>
      </form>
    </FormProvider>
  );
}

function PersonalInfoStep() {
  const { register, formState: { errors } } = useFormContext<MultiStepFormData>();
  return (
    <div>
      <input {...register("firstName", { required: "必須項目です" })} />
      <input {...register("lastName", { required: "必須項目です" })} />
      <input {...register("email", { required: "必須項目です" })} />
    </div>
  );
}

カスタムfieldcomponent

再利用possibleなfieldcomponentを設計するpattern है।

import { Controller, useFormContext, FieldPath } from "react-hook-form";

interface FormFieldProps<T extends Record<string, any>> {
  name: FieldPath<T>;
  label: string;
  type?: "text" | "email" | "number" | "textarea";
  placeholder?: string;
}

function FormField<T extends Record<string, any>>({
  name,
  label,
  type = "text",
  placeholder,
}: FormFieldProps<T>) {
  const { register, formState: { errors } } = useFormContext<T>();
  const error = errors[name];

  return (
    <div className="form-field">
      <label htmlFor={name}>{label}</label>
      {type === "textarea" ? (
        <textarea id={name} {...register(name)} placeholder={placeholder} />
      ) : (
        <input id={name} type={type} {...register(name)} placeholder={placeholder} />
      )}
      {error && <p className="error">{error.message as string}</p>}
    </div>
  );
}

Summary

React Hook Formは非制御componentベースのアプローチ से、大規模なformでも優れたperformanceを発揮し है।Claude Code का लाभ उठाकर、validationintegration、動的field、マルチステップform आदिのcomplexなpatternもकम समय मेंimplementationpossible है।

validationके details के लिएZodvalidation実践ガイドを、UIcomponentとのintegrationはRadix UIcomponentutilizationをदेखें。React Hook Formofficial documentationもconfirmしておきましょう。

#Claude Code #React Hook Form #React #forms #validation