目的
reactのform componentを書くときに入力値をstateで管理して、stateまみれのcomponentを作ってしまって可読性を下げてしまうことってありませんか? 例えば、こんな感じ。
import {NextPage} from 'next'; import {useState} from 'react'; const StartPage: NextPage = () => { const [example, setExample] = useState(''); const [exampleRequired, setExampleRequired] = useState(''); return ( <form> <input name="example" value={example} onChange={(e): void => setExample(e.target.value)} /> <input name="exampleRequired" value={exampleRequired} onChange={(e): void => setExampleRequired(e.target.value)} /> <input type="submit" /> </form> ); }; export default StartPage;
項目数が少ないと上記のようなコードでも大丈夫ですが、項目数が増えて、さらに、項目ごとのエラーをstateで管理するってなったら、state地獄になってしまいますよね。
stateを乱立させずに、入力値を管理できるようにしたい。
そんな時に使用するのが、react-hook-formです。
導入手順
導入の仕方はすごく簡単で、以下のライブラリをinstallするだけです。ほかに依存しているライブラリなどはありません。
npm install react-hook-form
改善
react-hook-formを導入すれば、目的で書いたよう例題はこのように改善されます。
import {NextPage} from 'next'; import {useForm} from 'react-hook-form'; const StartPage: NextPage = () => { const { register, handleSubmit, watch, formState: { errors }, } = useForm(); const onSubmit = (data: any): void => console.log(data); // watch input value by passing the name of it console.log(watch('example')); return ( <form onSubmit={handleSubmit(onSubmit)}> {/* register your input into the hook by invoking the "register" function */} <input defaultValue="test" {...register('example')} /> {/* include validation with required or other standard HTML validation rules */} <input {...register('exampleRequired', { required: true })} /> {/* errors will return when field validation fails */} {errors.exampleRequired && <span>This field is required</span>} <input type="submit" /> </form> ); };
引用元#exaple
ポイント
- exampleやexapleRequiredなどの個別のstateを用意せずに済む。
- useFormのhooksでformのhande処理、項目のエラーなど様々なものが用意されている。
簡単な解説
まず、初めに、useFormでreact-hook-formを使用する準備を行います。
const { register, handleSubmit, watch, formState: { errors }, } = useForm();
register
registerはinputタグに使用します。使用する際に名前(exaple)を付与して、以後はその名前でvalue値を取得できるようになります。
<input defaultValue="test" {...register('example')} />
hadlesumit
formのonSubmitの処理をhadleするのに使用します。
<form onSubmit={handleSubmit(onSubmit)}>
watch
inputで付与した名前に対して、値を監視することができます。
console.log(watch('example'));
formState
エラーなどのformに関する値を様々に管理しています。
{errors.exampleRequired && <span>This field is required</span>}
実際に画面を動かしてみた
値を入力して送信ボタンを押したところ、consoleにexampleとexampleRequired の値が確認できる。
TypeScriptでFormの型を指定する場合
typeを作成し、useFormのジェネリクスに型を指定すれば、Formのデータ型を指定することができ、registerでtype以外の名前を使用することができなくなる。
type FormType = { example: string; exampleRequired: string; }; const StartPage: NextPage = () => { const { register, handleSubmit, watch, formState: { errors }, } = useForm<FormType>(); const onSubmit = (data: any): void => console.log(data); // watch input value by passing the name of it console.log(watch('example')); return ( <form onSubmit={handleSubmit(onSubmit)}> {/* register your input into the hook by invoking the "register" function */} <input defaultValue="test" {...register('example')} /> {/* include validation with required or other standard HTML validation rules */} <input {...register('exampleRequired', { required: true })} /> {/* errors will return when field validation fails */} {errors.exampleRequired && <span>This field is required</span>} <input type="submit" /> </form> ); }; export default StartPage;
まとめ
state管理に苦しまなずに済む。
おススメのライトノベルです。是非、ぽちってください。