react-hook-form v7 `watch` 在打字稿中输入?
react-hook-form v7 `watch` type in typescript?
我对如何将 watch
的类型声明为道具感到困惑。这是一个例子:
// pages/FormContainer.tsx
import { useForm, useWatch } from "react-hook-form";
import FormView from "./FormView";
interface FormInputs {
firstName: string;
lastName: string;
age: number;
}
const FormContainer = () => {
const { control, register } = useForm<FormInputs>({
defaultValues: {
firstName: "Jon",
lastName: "Doe",
age: 24
}
});
const formData = useWatch({ control });
return <FormView register={register} formData={formData} />;
};
export default FormContainer;
// pages/FormView.tsx
import { UseFormReturn } from "react-hook-form";
interface Props {
register: UseFormReturn["register"];
formData: UseFormReturn["watch"];
}
const FormView = ({ formData }: Props) => {
return (
<div>
<h1>
My Name: {formData.firstName} {formData.lastName}
</h1>
<h2>I am {formData.age} years old</h2>
</div>
);
};
export default FormView;
问题是 typescript 向我显示了这个 formData={formData}
prop
的错误
这里我提供了一个sandbox来明确我的意思
UseFormReturn["watch"]
会给你返回 watch
函数本身的类型——也就是这个函数的类型:
// `watch` here is of type `UseFormReturn["watch"]
const { control, register, watch } = useForm<FormInputs>({
// ...
});
供参考,此 watch
函数的 return 类型为 UnpackNestedValues<TFormValues>
。
但是 - 您没有使用该功能,您使用的是 useWatch
,return 与 UnpackNestedValue<DeepPartialSkipArrayKey<TFieldValues>>
略有不同。因此,您可以将表单类型更改为:
import { UnpackNestedValue, UseFormReturn, DeepPartialSkipArrayKey } from "react-hook-form";
import { FormInputs } from "./FormContainer";
interface Props {
register: UseFormReturn["register"];
formData: UnpackNestedValue<DeepPartialSkipArrayKey<FormInputs>>
}
或者,由于您的表单对象(至少在本例中)非常“简单”(实际上只是 key/value 对),您可以使用更简单的 Partial<FormInputs>
类型声明,即在这种情况下功能等效。
我发现了 2 件事可以改善和解决您的问题。
- 使用从
useForm
返回的方法 watch
而不是 useWatch
来获取完整的表单数据。您可以使用 useWatch
进行单个表单输入更改,而不会影响根组件的呈现。
// Empty watch function will return the full form data.
const formData = watch()
watch
returns 完整的表单数据,所以 FormView
组件中的属性将是 FormInputs
.
interface Props {
register: UseFormReturn["register"];
formData: FormInputs;
}
这应该可以修复您的 TS 错误。
我对如何将 watch
的类型声明为道具感到困惑。这是一个例子:
// pages/FormContainer.tsx
import { useForm, useWatch } from "react-hook-form";
import FormView from "./FormView";
interface FormInputs {
firstName: string;
lastName: string;
age: number;
}
const FormContainer = () => {
const { control, register } = useForm<FormInputs>({
defaultValues: {
firstName: "Jon",
lastName: "Doe",
age: 24
}
});
const formData = useWatch({ control });
return <FormView register={register} formData={formData} />;
};
export default FormContainer;
// pages/FormView.tsx
import { UseFormReturn } from "react-hook-form";
interface Props {
register: UseFormReturn["register"];
formData: UseFormReturn["watch"];
}
const FormView = ({ formData }: Props) => {
return (
<div>
<h1>
My Name: {formData.firstName} {formData.lastName}
</h1>
<h2>I am {formData.age} years old</h2>
</div>
);
};
export default FormView;
问题是 typescript 向我显示了这个 formData={formData}
prop
这里我提供了一个sandbox来明确我的意思
UseFormReturn["watch"]
会给你返回 watch
函数本身的类型——也就是这个函数的类型:
// `watch` here is of type `UseFormReturn["watch"]
const { control, register, watch } = useForm<FormInputs>({
// ...
});
供参考,此 watch
函数的 return 类型为 UnpackNestedValues<TFormValues>
。
但是 - 您没有使用该功能,您使用的是 useWatch
,return 与 UnpackNestedValue<DeepPartialSkipArrayKey<TFieldValues>>
略有不同。因此,您可以将表单类型更改为:
import { UnpackNestedValue, UseFormReturn, DeepPartialSkipArrayKey } from "react-hook-form";
import { FormInputs } from "./FormContainer";
interface Props {
register: UseFormReturn["register"];
formData: UnpackNestedValue<DeepPartialSkipArrayKey<FormInputs>>
}
或者,由于您的表单对象(至少在本例中)非常“简单”(实际上只是 key/value 对),您可以使用更简单的 Partial<FormInputs>
类型声明,即在这种情况下功能等效。
我发现了 2 件事可以改善和解决您的问题。
- 使用从
useForm
返回的方法watch
而不是useWatch
来获取完整的表单数据。您可以使用useWatch
进行单个表单输入更改,而不会影响根组件的呈现。
// Empty watch function will return the full form data.
const formData = watch()
watch
returns 完整的表单数据,所以FormView
组件中的属性将是FormInputs
.
interface Props {
register: UseFormReturn["register"];
formData: FormInputs;
}
这应该可以修复您的 TS 错误。