【发布时间】:2020-10-13 09:21:12
【问题描述】:
我在react-hook-form 中使用自定义register,当我在输入中输入文本时,我无法将formState.isValid 变为true(因此满足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>
);
}
问题是针对这种类型的register 使用,而不是其他类型(ref 或Controller)。
Here 是一个完整的例子。
有人知道为什么会这样,我错过了什么吗?
另外,但这不太相关 - 有谁知道为什么每次输入更改都会触发两次渲染?
编辑
与丹尼斯·瓦什讨论后,在这个问题上取得了一些进展,但仍未解决。
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)
在我写这篇文章的时候,文档引用了react-form-hook 的第 5 版,我实际上使用的是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 时发生,但在false 时停止。
你可以试试here。输入一个键会开始不断的重新渲染,清除输入会停止循环...
【问题讨论】: