Form内でEnterキーを押した際の意図せぬSubmitを防ぐ方法
react-hook-formで作成したForm内でEnterキーを押すと、Submitが走り、勝手に次の未入力のinputにカーソルが移動したり、画面がリロードされます。
バリデーションを設けていない項目などは、入力途中にも関わらず(入力確定状態で)Enterを押すと勝手にリロード処理が走りform内容のpostリクエストがとんでしまう。ブラウザバックすると入力内容全てが消えている。。。
この動きはユーザー側からするとかなりダルい挙動なので、useStateとpreventDefaultでこれを制御してみました。
メモは要点のみでreact-hook-formの細かな設定やinputコンポーネント内のpropsや型の宣言等は割愛してます。
UserForm.tsx
import { useContext, useEffect, useState } from 'react';
const UserForm: NextPage<Props> = ({ user }: Props) => {
...
// ①入力しているか、していないかの状態をこのstateで管理します、デフォはtrue
const [completeState, setCompleteState] = useState<boolean>(true);
...
const onSubmit: SubmitHandler<HogeValues> = (input) => {
// postリクエスト処理実行関数
};
return (
// ③Inputにカーソルが入っている時はpreventDefaultでsubmitスルー、カーソルが外れたらreact-hook-formのhandleSubmitが判定されsubmitスタンバイ状態=下のボタンでpost可能な状態になります。通常のformなら単純にpreventDefaultをセットするだけで良いみたいですが、react-hook-formで作っている場合だとうまくいかず、stateのboolによるreact-hook-form実行or preventDefaultの判定を設けました。
<form
onSubmit={
completeState
? handleSubmit(onSubmit) //handleSubmitはreact-hook-formの関数
: (e) => {
e.preventDefault();
}
}
>
// ②Inputに対して「カーソルが入っている時はfalse」「カーソルが外れた時はtrue」という状態をもたせます
<Title>情報を入力してください</Title>
<Input
labelName='姓'
name='lastName'
type='text'
control={control}
error={errors.lastName?.message}
onBlur={() => setCompleteState(true)}
onFocus={() => setCompleteState(false)}
/>
<Input
labelName='名'
name='firstName'
type='text'
control={control}
error={errors.firstName?.message}
onBlur={() => setCompleteState(true)}
onFocus={() => setCompleteState(false)}
/>
<Button>確定</Button>
</form>
);
};
export default UserForm;
..