React Hook Formの基本まとめ その4(formProviderで親子間でフォーム情報をやりとりする)
こんにちは! 今回はReact Hook Formの基本まとめの4回目(最終回)です。
formProvider
親コンポーネント
import { useForm, FormProvider } from 'react-hook-form' import ChildComponent from '/ChildComponent'; const ParentForm = () => { const methods = useForm() const onSubmit = (data) => { console.log(data) } return ( <FormProvider {...methods}> <form onSubmit={methods.handleSubmit(onSubmit)}> <ChildComponent /> <button type="submit">送信</button> </form> </FormProvider> ) }
解説
FormProvider
- FormProviderで囲われたChildrenは、useFormContextを使うことでFormProviderが提供する値にアクセスできる
- FormProviderは
<FormProvider { ...methods } >のように、提供する値を指定できる - この例では、methodsはuseFormが返す値を全て保持しており、スプレッド構文ですべてを提供している
methods
- useFormでmethodsという変数(名前はなんでもよい)に戻り値を格納しているのは、FormProviderでまとめてすべての値を渡すときに都合が良いため
- これまでは、
const { control, handleSubmit } = useForm()のように、戻り値の中から指定して分割代入していたが、Providerにまとめて渡すのに都合が良いので、分割代入せずに受け取っている
methods.handleSubmit
- これまではhandleSubmitはuseFormから分割代入していたので、handleSubmitと使えていたが、今回は分割代入していないので、methods.handleSubmitと指定する必要がある
子コンポーネント
import { useFormContext, Controller } from 'react-hook-form' import { TextField } from '@mui/material' const ChildComponent = () => { const { control } = useFormContext(); return ( <Controller name="name" control={control} render={({ field, fieldState }) => ( <TextField {...field} error={!!fieldState.error} helperText={fieldState.error?.message} /> )} /> <Controller name="age" control={control} render={({ field, fieldState }) => ( <TextField {...field} type="number" error={!!fieldState.error} helperText={fieldState.error?.message} /> )} /> ) }
解説
useFormContext
- 親にFormProviderが存在する場合に使用可能
- 親のFormProviderが渡しているデータを取得可能
- 今回は
const { control } = useFormContext();としているので、controlを受け取っている - この control を使うことで、親のRHFにフォームの入力値を渡したり状態の管理をさせることができる
useWatch
- サンプルコードでは使っていないが、フォームの値をリアルタイムに取得できるメソッド
const name = useWatch({ control, name: "name" })
- 監視対象のcontrolと、取得したいフォームの名前を指定する
おわりに
これでReact Hook Formの基本まとめはひとまず終了です。順を追って見ていったおかげで、何とかコンポーネントをまたぐProviderの使い方までたどり着くことができました。ちなみに、学習方法はChatGPTに色々質問したことをベースにまとめているので、もしかすると古い情報や誤りがあるかもしれません。気づいたことがあれば適宜直していこうと思います。