简体   繁体   English

typescript 中的 react-hook-form v7 `watch` 类型?

[英]react-hook-form v7 `watch` type in typescript?

I am confused about how to declare a type for watch as a prop.我对如何将watch的类型声明为道具感到困惑。 Here is an example:这是一个例子:

// 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;

The thing is typescript shows me an error on this formData={formData} prop事情是 typescript 在这个formData={formData}道具上显示一个错误

Here I provided asandbox to be clear on what I mean在这里,我提供了一个沙箱来明确我的意思

UseFormReturn["watch"] will give you back the type of the watch function itself - that is, the type of this function: UseFormReturn["watch"]将返回watch function 本身的类型 - 即此 function 的类型:

  // `watch` here is of type `UseFormReturn["watch"]
  const { control, register, watch } = useForm<FormInputs>({
    // ...
  });

For reference, the return type of this watch function is UnpackNestedValues<TFormValues> .作为参考,此watch function 的返回类型为UnpackNestedValues<TFormValues>

But - you're not using that function, you're using useWatch which returns a subtly different UnpackNestedValue<DeepPartialSkipArrayKey<TFieldValues>> .但是 - 你没有使用 function,你使用的是useWatch ,它返回一个略有不同的UnpackNestedValue<DeepPartialSkipArrayKey<TFieldValues>> So, you could change your form type to that:因此,您可以将表单类型更改为:

import { UnpackNestedValue, UseFormReturn, DeepPartialSkipArrayKey } from "react-hook-form";
import { FormInputs } from "./FormContainer";

interface Props {
  register: UseFormReturn["register"];
  formData: UnpackNestedValue<DeepPartialSkipArrayKey<FormInputs>>
}

Alternatively, since your form object (at least in this example) is very "simple" (it's just key/value pairs effectively), you could use the simpler type declaration of Partial<FormInputs> which is functionally equivalent in this case.或者,由于您的表单 object(至少在此示例中)非常“简单”(实际上只是键/值对),您可以使用更简单的Partial<FormInputs>类型声明,它在这种情况下功能等效。

Here's an updated example for you .这是为您更新的示例

I found 2 things that will improve and fix your problem.我发现了两件事可以改善和解决您的问题。

  1. Use the method watch returned from useForm instead of useWatch for getting full form data.使用从useForm返回的方法watch而不是useWatch来获取完整的表单数据。 You can use useWatch for individual form input changes without impacting the root component's render.您可以将useWatch用于单个表单输入更改,而不会影响根组件的呈现。
// Empty watch function will return the full form data.
const formData = watch()
  1. watch returns the full form data, so the prop in the FormView component will be FormInputs . watch返回完整的表单数据,因此FormView组件中的 prop 将是FormInputs
interface Props {
  register: UseFormReturn["register"];
  formData: FormInputs;
}

This should fix your TS errors.这应该可以修复您的 TS 错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM