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 Hook FormでhandleSubmitを呼んでもバリデーションエラーが表示されなかった

0
Posted at

概要

React Hook Formでフォームを送信したときに、バリデーションエラーが表示されませんでした。

やりたいこと

フォームを送信したときに、入力内容に問題があればバリデーションエラーを表示したいです。

実行したコード

StorybookのInteraction Testで、何も入力せずに送信ボタンをクリックします。

export const SubmitFormError: Story = {
  play: async ({ step, canvas, userEvent }) => {
    await step("入力せずに送信するとエラーが表示される", async () => {
      await userEvent.click(canvas.getByRole("button", { name: "送信" }));

      await expect(canvas.getByText("入力は必須です")).toBeVisible();
    });
  },
};

フォームでは以下のように実装していました。

export const SampleForm = () => {
  const {
    register,
    formState: { errors },
    handleSubmit,
  } = useForm<SampleSchema>({
    resolver: zodResolver(sampleSchema),
    mode: "onChange",
  });

  const onSubmit = () => console.log("submit");

  return (
    <form
      noValidate
      onSubmit={(e) => {
        e.preventDefault();
        void handleSubmit(onSubmit);
      }}
    >
      <label htmlFor="message">入力</label>
      <input id="message" {...register("message")} />
      <p>{errors.message?.message}</p>
      <button>送信</button>
    </form>
  );
};

問題

送信ボタンをクリックしても、期待していたバリデーションエラーが表示されませんでした。

原因調査

他で実装していたフォームと比較しました。

<form
  onSubmit={(e) => {
    return void handleSubmit(onSubmit)(e);
  }}
  noValidate
>

比較すると、問題が発生したコードでは以下のようになっていました。

void handleSubmit(onSubmit);

原因

handleSubmit(onSubmit)が返す関数を実行していなかったことが原因でした。

handleSubmit(onSubmit)を呼び出すだけではなく、返された関数を実行する必要があります。

handleSubmit(onSubmit)(e);

解決策

handleSubmit(onSubmit)が返した関数を、submitイベントを渡して実行するように変更しました。

export const SampleForm = () => {
  const {
    register,
    formState: { errors },
    handleSubmit,
  } = useForm<SampleSchema>({
    resolver: zodResolver(sampleSchema),
    mode: "onChange",
  });

  const onSubmit = () => console.log("submit");

  return (
    <form
      noValidate
      onSubmit={(e) => {
        e.preventDefault();
        void handleSubmit(onSubmit)(e);
      }}
    >
      <label htmlFor="message">入力</label>
      <input id="message" {...register("message")} />
      <p>{errors.message?.message}</p>
      <button>送信</button>
    </form>
  );
};

修正した箇所は以下です。

void handleSubmit(onSubmit)(e);

学んだこと

handleSubmit(onSubmit)は、その場でonSubmitを実行するものではなく、フォームのsubmitイベントを処理するための関数を返します。

そのため、今回のようにonSubmit内で呼び出す場合は、返された関数を実行する必要があります。

参考

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?