我在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>
);
}
使用,而不是其他类型(register
或ref
)。
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。输入键将开始连续重新渲染,清除输入将停止循环...
答案 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>
);
}
答案 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”将按预期工作。