1
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、ChakraUIのダイアログでバリデーション、Saveを両立させる方法

Posted at

はじめに

問題に直面したので、記事にまとめます。

問題

ダイアログを閉じる動作、データを保存する動作、バリデーションエラーを表示する動作を両立できませんでした。

(1) DialogActionTriggerを使う場合
React Hook Formを使用していて、バリデーションが通らないはずなのに、Saveボタンを押せてしまいます。
(学習内容や学習時間を空白にするとエラーになるはずが、押せてしまう)

ダイアログ
image.png

src/App.tsx
<div>
    <label htmlFor="studyContent">学習内容</label>
    <input
        id="studyContent"
        type="text"
        {...register('studyContent', {
            required: '内容の入力は必須です',
        })}
    />
    {errors['studyContent'] && (
        <p>{errors['studyContent'].message}</p>
    )}
</div>

<DialogActionTrigger asChild>
    <button type="submit" disabled={true}>Save</button>
</DialogActionTrigger>

ChakraUIのトリガーを使っているため、保存ボタンを押すとダイアログが閉じてしまいます。
再度、登録ボタンを押すとエラーが表示されます。
image.png

(2) DialogActionTriggerを使わない場合

src/App.tsx
// <DialogActionTrigger asChild>
    <button type="submit" disabled={true}>Save</button>
// </DialogActionTrigger>

Saveボタンを押すとダイアログが閉じずにエラーを表示できます。
しかし、正しく入力すると、登録はできるがダイアログが開いたままになります。

(テスト 2時間が登録できたが、ダイアログが開いたまま)
image.png

解決方法

watchでstudyHourの状態を監視し、バリデーションが通る場合はDialogActionTriggerを使ってダイアログを閉じ、バリデーションが通らない場合はDialogActionTriggerを外してダイアログを閉じないようにしました。

src/App.tsx
const { register, handleSubmit, formState: { errors }, reset, watch } = useForm<FormValues>();

// 監視用のwatchを定義
const studyContent = watch('studyContent', '');
const studyHour = watch('studyHour', null);

{studyContent && studyHour && studyHour >= 0 ? (
    <DialogActionTrigger asChild>
        <button type="submit">Save</button>
    </DialogActionTrigger>
) : (
    <button type="submit">Save</button>
)}

おわりに

終わってみれば複雑ではなさそうですが、解決するのに3、4日かかってしまいました。

1
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
1
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?