React Hook Formを使う
開発のプロジェクトで「ReactHookFormで実装して」と言われて触る機会があり,初心者なりに何度か詰まってから理解したので,つまらない用に超絶簡易ドキュメントを書く.
React Hook Formとは
特徴
- onChangeを走らせずにすみパフォーマンスがつおい
- inputやselectのvalueをsubmitのときに拾ってくれる
多分他にもっとある
install
npm
npm install react-hook-form
yarn
yarn add react-hook-form
普通に使う
公式から持ってきたサンプルを説明します.
import React from "react"
import { useForm } from "react-hook-form"
export default function App() {
const { register, handleSubmit, watch, errors } = useForm()
const onSubmit = data => console.log(data)
console.log(watch("example")); // watch input value by passing the name of it
return (
{/* "handleSubmit" will validate your inputs before invoking "onSubmit" */}
<form onSubmit={handleSubmit(onSubmit)}>
{/* register your input into the hook by invoking the "register" function */}
<input name="example" defaultValue="test" ref={register} />
{/* include validation with required or other standard HTML validation rules */}
<input name="exampleRequired" ref={register({ required: true })} />
{/* errors will return when field validation fails */}
{errors.exampleRequired && <span>This field is required</span>}
<input type="submit" />
</form>
);
}
useFormをimportする
import { useForm } from "react-hook-form"
必要なものを分割代入して使う
const { register, handleSubmit, watch, errors } = useForm()
最低限register
とhandleSubmit
は必要になるかな
監視対象にregisterを設定
<input name="example" defaultValue="test" ref={register} />
ref属性がregister
がであるものを監視
registerは以下のように引数にオブジェクトを渡すことで,バリデーションの設定ができる
ref={register({ required: true })}
その他の詳細設定はここを参照↓
https://react-hook-form.com/jp/api#register
送信の設定
<form onSubmit={handleSubmit(onSubmit)}>
formタグのonSubmit属性にhandleSubmit()
を設定.この引数にフォームを送信する関数を渡す
今回は,const onSubmit = data => console.log(data)
が実行される
仕組みは,refにregisterが設定された要素のvalueが,その要素のnameがプロパティとなり,dataにオブジェクトとして渡される.
今回であれば,
data = {example: "入力されたvalue",exampleRequired: "入力されたvalue"}
と言った具合
バリデーションのエラーメッセージ
registerに関するエラーは,
const { register, handleSubmit, watch, errors } = useForm()
で定義したerrors
に返ってくるので
errors.exampleRequired
とすれば呼び出せる
外部ライブラリに対応した使い方
さて,便利なHookFormだが,Material-UIなどのツールと共存すると正常に動作しないので困る.
ここをよくわかっていないと,「Material-UIと共存できないとかwww 使う意味なくね?wwww」と言われる.
制御ができない場合はControllerコンポーネントを使って制御する
制御ができない場合とはref属性を設定することができないもののようです.
Controllerをimportする
import { useForm, Controller } from "react-hook-form";
もちろんuseFormも忘れずに
controlを定義しておく
const { handleSubmit, register, errors, control } = useForm();
こんな感じに,普通に使い場合に加えて,Controllerコンポーネントとcontrolを準備する.
外部ライブラリのコンポーネントを制御する書き方
今回のサンプルはみんな大好きMaterialUI
<Controller
name="gender"
// control属性忘れずに
control={control}
// component
as={
<RadioGroup aria-label="gender" name="gender1" >
<FormControlLabel value="female" control={<Radio />} label="Female" />
<FormControlLabel value="male" control={<Radio />} label="Male" />
<FormControlLabel value="other" control={<Radio />} label="Other" />
<FormControlLabel value="disabled" disabled control={<Radio />} label="(Disabled option)" />
</RadioGroup>
// validation
rules={{ required: true }}
}
/>
オブジェクトのプロパティとなるname属性をセットしましょう
name="gender"
先程定義したcontrol属性もこんな感じにセットします
control={control}
そして制御したいコンポーネントをasに入れます.
今回はMaterialUIのラジオボタンです.
また,このControllerコンポーネントを使用した場合はregisterを使わないので,バリデーションどーすんの?となる.この場合はrules属性を使う.ここがドキュメントちゃんと読んでいなかったので詰まった😣
rules={{ required: true }}
こんな感じでOK
欠点
TypeScriptとの相性がわるい(かもしれない)
試してはないし,よくわかっていない🤤
Discussion