我正在使用 react-hook-form
中的自定义 register
,但是当我在输入框中输入文本(并满足 required
条件)时,无法获取 formState.isValid
为 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 });
}, [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
)。
这里有一个完整的例子。
有人知道为什么会这样吗?我错过了什么吗?
此外,但这不太相关 - 有人知道为什么每次输入更改都会触发两次渲染吗?
编辑
在与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)
在我撰写此文时,文档引用react-form-hook
的版本为5,而我目前使用的是6.0.0-rc.5
,因此签名发生了一些变化,类似于以下内容:
(name: string, value: any, { shouldValidate: boolean; shouldDirty: boolean; }) => void
然而,在我的一个例子中,当使用 shouldValidate: true
时,我遇到了无限循环的问题:
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
时停止。
您可以在此处试用。输入一个键将开始连续重新渲染,清除输入将停止循环...
onChange
,但它并没有起作用。也许我当时还是做错了什么,或者可能是react-hook-form
中的一个错误,后来被修复了。完整的示例链接也不再有效,所以我不能确定。 - mrzli