</> useWatch:
({ control?: Control, name?: string, defaultValue?: unknown, disabled?: boolean }) => object
watch
API に類似した動作をするが、カスタムフックレベルで再レンダリングを分離することによって、アプリケーションのパフォーマンスが向上する可能性がある。
小道具
名前 | タイプ | 説明 |
---|---|---|
name | string | string[] | undefined | フィールドの名前。 |
control | Object | useForm によって提供される control オブジェクト。FormProvider を使用している場合は省略可能です。 |
defaultValue | unknown | useWatch が最初のレンダリングの前に返す defaultValue 。注: 最初のレンダリングでは、供給された場合常に defaultValue が返されます。 |
disabled | boolean = false | 購読を無効にするオプション。 |
exact | boolean = false | この小道具は入力名購読の完全一致を有効にします。 |
リターン
例 | リターン |
---|---|
useWatch({ name: 'inputName' }) | unknown |
useWatch({ name: ['inputName1'] }) | unknown[] |
useWatch() | {[key:string]: unknown} |
ルール
-
useWatch
からの最初の戻り値は、常にuseForm
のdefaultValue
またはdefaultValues
に含まれるものになります。 -
useWatch
とwatch
の唯一の違いは、ルート(useForm
)レベルまたはカスタムフックレベルの更新です。 -
useWatch
の実行順序が問題になります。つまり、購読が完了する前にフォームの値を更新すると、更新された値は無視されます。setValue("test", "data")useWatch({ name: "test" }) // ❌ subscription is happened after value update, no update receiveduseWatch({ name: "example" }) // ✅ input value update will be received and trigger re-rendersetValue("example", "data")次の簡単なカスタムフックを使用して、上記の問題を克服できます
const useFormValues = () => {const { getValues } = useFormContext()return {...useWatch(), // subscribe to form value updates...getValues(), // always merge with latest form values}} -
useWatch
の結果は、値の更新を検出するために外部の custom hook を使用する、useEffect
の deps の代わりにレンダリングフェーズ用に最適化されています。
例
フォーム
import React from "react"import { useForm, useWatch } from "react-hook-form"interface FormInputs {firstName: stringlastName: string}function FirstNameWatched({ control }: { control: Control<FormInputs> }) {const firstName = useWatch({control,name: "firstName", // without supply name will watch the entire form, or ['firstName', 'lastName'] to watch bothdefaultValue: "default", // default value before the render})return <p>Watch: {firstName}</p> // only re-render at the custom hook level, when firstName changes}function App() {const { register, control, handleSubmit } = useForm<FormInputs>()const onSubmit = (data: FormInputs) => {console.log(data)}return (<form onSubmit={handleSubmit(onSubmit)}><label>First Name:</label><input {...register("firstName")} /><input {...register("lastName")} /><input type="submit" /><FirstNameWatched control={control} /></form>)}
高度なフィールド配列
import React from "react"import { useWatch } from "react-hook-form"function totalCal(results) {let totalValue = 0for (const key in results) {for (const value in results[key]) {if (typeof results[key][value] === "string") {const output = parseInt(results[key][value], 10)totalValue = totalValue + (Number.isNaN(output) ? 0 : output)} else {totalValue = totalValue + totalCal(results[key][value], totalValue)}}}return totalValue}export const Calc = ({ control, setValue }) => {const results = useWatch({ control, name: "test" })const output = totalCal(results)// isolated re-render to calc the result with Field Arrayconsole.log(results)setValue("total", output)return <p>{output}</p>}
ご支援いただきありがとうございます。
React Hook Form がプロジェクトで役立っている場合は、スターを付けてサポートをご検討ください。