“ isValid”始终为假

时间:2020-06-23 10:29:01

标签: reactjs react-hook-form

我在register中使用了自定义react-hook-form,在输入文本时我无法使formState.isValid成为true(因此满足{ {1}}条件。

这是示例代码:

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> ); } 使用,而不是其他类型(registerref)。

Here是一个完整的例子。

有人知道为什么会这样吗,我想念什么?

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

编辑

与Dennis Vash讨论后,在此问题上取得了一些进展,但仍未解决。

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

Controller

在撰写本文时,文档引用的是(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) 的第5版,我实际上使用的是react-form-hook,因此签名有点类似于以下内容:

6.0.0-rc.5

但是,在使用(name: string, value: any, { shouldValidate: boolean; shouldDirty: boolean; }) => void 的示例中,出现了无限循环:

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> ); } isValid时发生循环,但当循环为true时停止循环。

您可以尝试here。输入键将开始连续重新渲染,清除输入将停止循环...

enter image description here

2 个答案:

答案 0 :(得分:2)

由于React.StrictMode,该组件呈现了两次。

严格模式无法自动为您检测副作用,但可以通过使其更具确定性来帮助您发现它们。为此,可以有意地重复调用以下功能:...

此外,为了验证您需要提交表单(尝试按enter),如果您在onChange模式下不使用引用,则应该使用triggerValidation。 / p>

export default function App() {
  const {
    register,
    formState,
    watch,
    errors,
    setValue,
    handleSubmit
  }: UseFormMethods<FormValues> = useForm<FormValues>();

  useEffect(() => {
    register(
      { name: "firstName", type: "custom" },
      { required: true, min: 1, minLength: 1 }
    );
    console.log("called");
  }, [register]);

  const { isValid } = formState;
  const values = watch("firstName");

  const onSubmit = (data, e) => {
    console.log("Submit event", e);
    console.log(JSON.stringify(data));
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
          setValue("firstName", e.target.value);
        }}
      />
      {/*<button>Click</button>*/}
      <div>IsValid: {JSON.stringify(isValid)}</div>
      <div>Errors: {JSON.stringify(errors)}</div>
      <div>Form value: {JSON.stringify(values)}</div>
    </form>
  );
}

Edit old-brook-ho66h

答案 1 :(得分:0)

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

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

const { register, handleSubmit, formState: { errors, isDirty, isValid }} = useForm({ mode: 'onChange' });

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