npm install react-hook-form
または
yarn add react-hook-form
import { useForm } from 'react-hook-form';
// React Hook Form
const {
register,
handleSubmit,
formState: { errors },
} = useForm();
const onSubmit = (data:any) => {alert('form送信されました'); console.log(data);}
useForm() には様々なオプションを渡すことができます
https://react-hook-form.com/api/useform/
useForm({
mode: 'onSubmit', // onChange | onBlur | onSubmit | onTouched | all = 'onSubmit'
reValidateMode: 'onChange',
defaultValues: {},
resolver: undefined,
context: undefined,
criteriaMode: "firstError",
shouldFocusError: true,
shouldUnregister: false,
shouldUseNativeValidation: false,
delayError: undefined
})
useForm() して返ってくる handleSubmitに (バリデーションOKの時の関数,バリデーションNGの時の関数) を渡します
handleSubmit(SubmitHandler, SubmitErrorHandler)
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('company', { required: true, minLength: 4 })} placeholder="株式会社○○" />
{errors.company?.type === "required" && <div className="err_message" id="company_err">会社名は必須です</div>}
{errors.company?.type === "minLength" && <div className="err_message" id="company_err">会社名は4文字以上を入力してください</div>}
<input type="submit" />
</form>
);
<input type="email" placeholder="user@server.xxx"
{...register("email", {
required: "入力必須です",
pattern: {
value: /\S+@\S+\.\S+/,
message: "メールアドレスが不完全です"
}
})}
/>
{errors.email && <div className="err_message">{errors.email.message}</div>}
https://react-hook-form.com/jp/api#register
バリデーションの記述をYupでまとめるには次のように記述します
npm install @hookform/resolvers yup
または
yarn add @hookform/resolvers yup
import { yupResolver } from '@hookform/resolvers/yup';
import * as Yup from 'yup';
const validationSchema = Yup.object().shape({
firstName: Yup.string()
.required('First Name は必須です'),
lastName: Yup.string()
.required('Last Name は必須です'),
});
const formOptions = { resolver: yupResolver(validationSchema) };
const { register, handleSubmit, reset, formState } = useForm(formOptions);
const { errors } = formState;
<form onSubmit={handleSubmit(onSubmit)}>
<input type="text" {...register('firstName')} className={`form-control ${errors.firstName ? 'is-invalid' : ''}`} />
<div className="invalid-feedback">{errors.firstName?.message}</div>
</form>
name="firstName" は記述しなくてokです。
外部からフォームの値を変更するには以下の2つの方法を使用します。
( なお、useState は使用できません )
次の二箇所にデータを流し込む命令をセットします
// ● SWR
const fetcher = (url: string) => axios(url)
.then((res) => {
reset(res.data); // 1. axiosでデータ取得時にデータをフォームに反映(Re-render)
return res.data
});
const { data, error, mutate } = useSWR(`http://localhost:8000/api/news/1`, fetcher);
// ● useForm
const formOptions = {
defaultValues: data, // 2. SWRのキャッシュがデータをすでに取得している場合はキャッシュからフォームに反映
};
const { control, register, handleSubmit, reset, formState: { errors } } = useForm(formOptions);
// ● React Hook Form
const { register, handleSubmit, setValue, formState } = useForm(formOptions);
setValueを使用します
// ● SWR
const fetcher = (url: string) => axios(url)
.then((res) => {
// 最初に1度だけフォームに値をセット
const data = res.data;
Object.keys(data).forEach(function (k) {
setValue(k, data[k]);
});
return res.data
});
const { data, error, mutate } = useSWR(`http://localhost:8000/api/news/${params.id}`, fetcher);
// swrによるfetchエラー時
if (error) return <div>failed to load</div>
{...register('hoge')} の記述が抜けている可能性がありますチェックしましょう。
<input type="text" id="hoge" {...register('hoge')} />
let customValidation = yup.object().shape({
beverage: yup
.string()
.test("is-tea", "${path} is not tea", value => value === "tea")
});
https://react-hook-form.com/api/useformstate
https://qiita.com/bluebill1049/items/f838bae7f3ed29e81fff
yarn add @hookform/devtools
import { DevTool } from '@hookform/devtools';
jsx
<DevTool control={control} placement="top-left" />
<form onSubmit={handleSubmit(onSubmit, onError)}>
.............
</form>
公式サンプル
https://github.com/react-hook-form/react-hook-form/tree/master/examples
React Hook Form 7 - Form Validation Example | Jason Watmore's Blog
jsonによるスキーマ定義をyupに変換する
https://github.com/kristianmandrup/schema-to-yup
yarn add schema-to-yup