【React】React Hook Formの "はじめる" を始めてみた Part4【Typescript】
この記事はReact Hook Formの公式サイトにあるはじめるの項目を元に構成されています。ReactとTypescriptのサンプルコードを使って解説しています。
こんにちは!らびです。今回はReact Hook Formに関する記事です。
公式サイトのチュートリアルを使って一緒に勉強していきましょう。
既存のフォームに適用する
今回のサンプルコードは既存のフォームに適用するということで、再利用を想定して関数化された入力フォームでの使い方です。ということで、React Hook FormのサンプルコードをReactのプロジェクトにうつしたものがこちらです。
import React from 'react'; import { Path, useForm, UseFormRegister, SubmitHandler } from "react-hook-form"; import {List, ListItem} from '@mui/material'; import ResponsiveDrawer from '../components/layout/ResponsiveDrawer'; interface IFormValues { "First Name": string; Age: number; } type InputProps = { label: Path<IFormValues>; register: UseFormRegister<IFormValues>; required: boolean; }; // The following component is an example of your existing Input Component const Input = ({ label, register, required }: InputProps) => ( <> <label>{label}</label> <input {...register(label, { required })} /> </> ); // you can use React.forwardRef to pass the ref too const Select = React.forwardRef< HTMLSelectElement, { label: string } & ReturnType<UseFormRegister<IFormValues>> >(({ onChange, onBlur, name, label }, ref) => ( <> <label>{label}</label> <select name={name} ref={ref} onChange={onChange} onBlur={onBlur}> <option value="20">20</option> <option value="30">30</option> </select> </> )); const Home4 = () => { const { register, handleSubmit } = useForm<IFormValues>(); const onSubmit: SubmitHandler<IFormValues> = (data) => { alert(JSON.stringify(data)); }; return ( <ResponsiveDrawer> <div> <form onSubmit={handleSubmit(onSubmit)}> <List> <ListItem> <label>First Name</label> <Input label="First Name" register={register} required /> </ListItem><ListItem> <label>Age</label> <Select label="Age" {...register("Age")} /> </ListItem><ListItem> <input type="submit" /> </ListItem> </List> </form> </div> </ResponsiveDrawer> ); } export default Home4;
InputとSelectという2つの関数化された入力フォームが定義されてるジョ。実行結果はこうなるジョ。
import
まずはimportです。今回はuseFormとSubmitHandlerの他にPathとUseFormRegisterをインポートしています。
import { Path, useForm, UseFormRegister, SubmitHandler } from "react-hook-form";
関数化された入力フォームで入力コンポーネントの登録をするのにPathとUseFormRegisterが必要なんですね。
const { register, handleSubmit } = useForm<IFormValues>();
useFormのジェネリクスパラメータとしてIFormValuesを渡しているジョ。
register
次は入力コンポーネントの登録です。今回はInputとSelectそれぞれの関数化された入力フォームについて見ていきましょう。
Inputの定義を見るとInputProps型の引数を取っていて、そこからlabel、register、requiredを取り出しています。
type InputProps = { label: Path<IFormValues>; register: UseFormRegister<IFormValues>; required: boolean; }; const Input = ({ label, register, required }: InputProps) => ( <> <label>{label}</label> <input {...register(label, { required })} /> </> ); …省略 <Input label="First Name" register={register} required /> …
関数の呼び出しを見ると、label、register、requiredをそれぞれ渡しています。
Selectの定義はforwardRefを使っています。forwardRefのジェネリクスパラメータはHTMLSelectElementと{ label: string } & ReturnType
ちょっと複雑なので、十分に時間をかけて整理するといいジョ。
UseFormRegisterReturnの定義を見ると、onChange, onBlur, nameの定義があるので、UseFormRegisterReturn型で引数が渡されているのが確認できますね。
const Select = React.forwardRef< HTMLSelectElement, { label: string } & ReturnType<UseFormRegister<IFormValues>> >(({ onChange, onBlur, name, label }, ref) => ( <> <label>{label}</label> <select name={name} ref={ref} onChange={onChange} onBlur={onBlur}> <option value="20">20</option> <option value="30">30</option> </select> </> )); …省略 <Select label="Age" {...register("Age")} /> …
UseFormRegisterReturnの定義
export declare type UseFormRegisterReturn = { onChange: ChangeHandler; onBlur: ChangeHandler; ref: RefCallBack; name: InternalFieldName; min?: string | number; max?: string | number; maxLength?: number; minLength?: number; pattern?: string; required?: boolean; disabled?: boolean; };
まとめ
というわけで、今回もReact Hook Formのはじめるについて勉強してきましたが、いかがでしたでしょうか?
再利用を想定して入力フォームを関数化してもReact Hook Formが利用できることが確認できました。
次回もぜひご覧ください。では!
参考
React Hook Form
react-hook-form.com