“isValid”始终为假

mrz*_*zli 7 reactjs react-hook-form

我使用自定义registerreact-hook-form,我无法得到formState.isValidtrue,当我输入文本输入(所以满足required条件)。

这是一个示例代码:

interface FormValues {
  readonly value: string;
}

export default function App() {
  console.log("rendering");

  const form: UseFormMethods<FormValues> = useForm<FormValues>({
    mode: "onChange",
    reValidateMode: "onChange",
    defaultValues: { value: "" }
  });

  useEffect(() => {
    form.register({ name: "value" }, { required: true });
  }, [form, form.register]);

  const { isValid } = form.formState;
  const value = form.watch("value");

  return (
    <div>
      <input
        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
          form.setValue("value", e.target.value);
        }}
      />
      <div>IsValid: {JSON.stringify(isValid)}</div>
      <div>Errors: {JSON.stringify(form.errors)}</div>
      <div>Value: {JSON.stringify(value)}</div>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

问题专门针对这种类型的register使用,而不是其他类型(refController)。

是一个完整的例子。

有人知道为什么会这样吗,我错过了什么?

此外,但这不太相关 - 有谁知道为什么每次输入更改都会触发两次渲染?

编辑

经过与 Dennis Vash 的讨论,这个问题有了一些进展,但仍然没有解决。

https://react-hook-form.com/api/#setValue 上的文档实际上确实指定了触发验证的选项:

(name: string, value: any, shouldValidate?: boolean) => void


You can also set the shouldValidate parameter to true in order to trigger a field validation. eg: setValue('name', 'value', true)

Run Code Online (Sandbox Code Playgroud)

在我写这篇文章的时候,文档指的是 的第 5 版react-form-hook,我实际上正在使用,6.0.0-rc.5所以签名有点改变,类似于以下内容:

(name: string, value: any, { shouldValidate: boolean; shouldDirty: boolean; }) => void
Run Code Online (Sandbox Code Playgroud)

但是,在我使用时的一个示例中shouldValidate: true,我得到了一个无限循环:

interface FormValues {
  readonly value: string;
}

export default function App() {
  console.log("rendering");

  const form: UseFormMethods<FormValues> = useForm<FormValues>({
    mode: "onChange",
    reValidateMode: "onChange",
    defaultValues: { value: "" }
  });

  useEffect(() => {
    form.register({ name: "value" }, { required: true, minLength: 1 });
  }, [form, form.register]);

  const { isValid } = form.formState;
  const value = form.getValues("value");

  return (
    <div>
      <input
        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
          form.setValue("value", e.target.value, {
            shouldValidate: true
          });
        }}
      />
      <div>IsValid: {JSON.stringify(isValid)}</div>
      <div>Errors: {JSON.stringify(form.errors)}</div>
      <div>Value: {JSON.stringify(value)}</div>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

循环在 是 时发生,但在isValidtrue时停止false

你可以在这里试一试。输入一个键将开始连续重新渲染,清除输入将停止循环......

在此处输入图片说明

小智 23

参考https://github.com/react-hook-form/react-hook-form/issues/2147

您需要将模式设置为 onChange 或 onBlur

const { register, handleSubmit, formState: { errors, isDirty, isValid }} = useForm({ mode: 'onChange' });
Run Code Online (Sandbox Code Playgroud)

在这种情况下,“isValid”将按预期工作。


Den*_*ash 5

该组件渲染了两次,因为React.StrictMode.

\n
\n

严格模式可以\xe2\x80\x99t自动为您检测副作用,但它可以通过使副作用更具确定性来帮助您发现它们。这是通过有意双重调用以下函数来完成的:...

\n
\n

另外,为了验证您需要提交表单(尝试按enter),如果您在onChange模式下不使用参考,您应该使用triggerValidation

\n
export default function App() {\n  const {\n    register,\n    formState,\n    watch,\n    errors,\n    setValue,\n    handleSubmit\n  }: UseFormMethods<FormValues> = useForm<FormValues>();\n\n  useEffect(() => {\n    register(\n      { name: "firstName", type: "custom" },\n      { required: true, min: 1, minLength: 1 }\n    );\n    console.log("called");\n  }, [register]);\n\n  const { isValid } = formState;\n  const values = watch("firstName");\n\n  const onSubmit = (data, e) => {\n    console.log("Submit event", e);\n    console.log(JSON.stringify(data));\n  };\n\n  return (\n    <form onSubmit={handleSubmit(onSubmit)}>\n      <input\n        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n          setValue("firstName", e.target.value);\n        }}\n      />\n      {/*<button>Click</button>*/}\n      <div>IsValid: {JSON.stringify(isValid)}</div>\n      <div>Errors: {JSON.stringify(errors)}</div>\n      <div>Form value: {JSON.stringify(values)}</div>\n    </form>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n

编辑 old-brook-ho66h

\n