Closed6
React Hook Form 初心者の気づきメモ
handleSubmit
の引数を使え
送信時にデータを使いたいときはhandleSubmit
には、引数にフォームのデータが入っている
Form.tsx
<form onSubmit={handleSubmit(data => onSubmit(data))}>
register
の後ろにref
を書け
DOMを参照したいときは'ref' is specified more than once, so this usage will be overwritten.
useRef
で<input />
のDOMを参照しようとすると、React Hook Formの参照と競合してエラーが出る。
上書きするためには、ref
をregister
より後ろに書く
Input.tsx
import { type FC, useRef } from 'react';
const Input: FC<{name: string, placeholder: string}> = ({ name, placeholder }) => {
const { register } = useFormContext();
const inputRef = useRef<HTMLInputElement>(null);
return (
<input
placeholder={placeholder}
{...register(name, { required: true })}
ref={inputRef} // refを上書き
/>
);
};
export default Input;
⚠️refを上書きしたときの注意点⚠️
useFormContext
を使っていると、参照がうまくいかずにisValid
が正常に動かなくなる。
From.tsx
import { type FC } from 'react';
import { useForm, FormProvider } from 'react-hook-form';
import Input from '@/components/Input';
const Form: FC<{name: string}> = ({ name }) => {
const { register } = useFormContext();
const onSubmit = () => console.log('送信');
return (
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)}>
<Input name="age" placeholder="年齢" />
<button disabled={!methods.formState.isValid}>送信</button> // Inputに入力しても活性にならない
</form>
</FormProvider>
);
};
export default Form;
readonly
を使え
編集不可にしたいときは(React Hook Form 関係ないが)
<input />
の属性をdisabled
にすると、フォームで送信されない。
送信すらも無効になってしまうので、編集不可かつ送信可能にしたい場合はreadonly
を使う。
Form.tsx
...
<Input name="age" placeholder="年齢" readOnly />
...
shouldValidate
を使え
値変更時にバリデーションをかけたいときはForm.tsx
const data = await getAddressByPostalCode();
setValue('prefecture', data.prefecture, { shouldValidate: true });
任意のタイミングでバリデーションをかけたいときは、trigger
が便利そう。
参考:useForm - setValue - React Hook Form
trigger - React Hook Form
isSubmitting
を使え
二重送信防止には簡単に二重送信防止できる
※onSubmit
の処理には、ちゃんとasync/awaitで終わるまで待つような処理を入れる
Input.tsx
import { type FC } from 'react';
const Input: FC<{name: string, placeholder: string}> = ({ name, placeholder }) => {
const methods = useForm();
return (
<input
placeholder={placeholder}
{...register(name, { required: true })}
disabled={!methods.formState.isValid || methods.formState.isSubmitting}
/>
);
};
export default Input;
isDirty
を使え
初期値からの変更を検知する場合はフォームの初期値(defaultValues
)から変更があった場合のみ送信できるようにしたい場合は、disable
に!isDirty
を使う
Input.tsx
const Input: FC = () => {
const { formState: { isDirty }} = useForm({defaultValues: {prefecture: '東京都'}});
return (
<input {...register("prefecture")} />
<button type="submit" disabled={!isDirty}>
);
};
このスクラップは2024/01/25にクローズされました