使用带有自定义 TextInput 的 React hook 表单

Are*_*ast 1 javascript reactjs react-hooks react-hook-form

我正在尝试将 React hook 形式与自定义 TextInput 结合使用。在我使用材料输入之前,一切都工作正常。我找到了一种可以实现这一目标的方法,但我对此并不满意。

我正在使用useForm钩子

  const {
    register,
    handleSubmit,
    formState: { errors, isValid },
  } = useForm<FormValues>({ resolver: yupResolver(schema), mode: "all" });
Run Code Online (Sandbox Code Playgroud)

我的自定义 TextField (非常简单,因为现在我只想将其注册到表单中):

export interface TextFieldProps {
    id: string;
    error: string | undefined;
    label: string;
    register: UseFormRegister<any>
}

const TextField = ({ id, error, label, register }: TextFieldProps): JSX.Element => {
    return <>
    <input {...register(`${id}`)}></input>
    {error}
    </>
  };
Run Code Online (Sandbox Code Playgroud)

使用该组件:

          <TextField
            register={register}
            id="username"
            label="Username"
            error={errors.username?.message}
          />
Run Code Online (Sandbox Code Playgroud)

这段代码可以工作,但我失去了IMO非常好的功能 - 检查我传递给注册函数的名称。例如,我声明了一些模式:

  const schema = yup.object({
    username: yup.string().required("Username is required"),
    password: yup.string().required("Password is required"),
  });
Run Code Online (Sandbox Code Playgroud)

如果我尝试下面的代码。Typescript 会说我的架构中没有电子邮件字段。

          <input
          {...register("email")}>
          </input>
Run Code Online (Sandbox Code Playgroud)

我仍在尝试修改 TextInput 组件以便能够像以下那样使用它:

          <TextField
            {...register("username")}
            id="username"
            label="Username"
            error={errors.username?.message}
          />
Run Code Online (Sandbox Code Playgroud)

但我仍然面临警告Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()? TextField 组件应该如何避免forwardRef 警告?

Jor*_*ris 6

你必须通过ref以下是实现这一目标的方法之一

export interface TextFieldProps extends React.PropsWithoutRef<JSX.IntrinsicElements["input"]> {
    error: string | undefined;
    label: string;
}

const TextField = forwardRef<HTMLInputElement, LabeledTextFieldProps>({ errorm label, ...props }, ref) => {
    return (
      <>
        <input {...props} ref={ref}></input>
        {error}
      </>
    )
  });

Run Code Online (Sandbox Code Playgroud)

您可以像这样使用它:

<TextField {...register('username')} label="Username label" error={formState.errors.username.message}/>
Run Code Online (Sandbox Code Playgroud)