📋

React Hook Formを使う

2020/12/14に公開

開発のプロジェクトで「ReactHookFormで実装して」と言われて触る機会があり,初心者なりに何度か詰まってから理解したので,つまらない用に超絶簡易ドキュメントを書く.

React Hook Formとは

https://react-hook-form.com/

特徴

  • 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()

最低限registerhandleSubmitは必要になるかな

監視対象に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