mrz*_*zli 7 reactjs react-hook-form
我使用自定义register的react-hook-form,我无法得到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>
);
}
Run Code Online (Sandbox Code Playgroud)
问题专门针对这种类型的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)
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)
循环在 是 时发生,但在isValid是true时停止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”将按预期工作。
该组件渲染了两次,因为React.StrictMode.
\n\n严格模式可以\xe2\x80\x99t自动为您检测副作用,但它可以通过使副作用更具确定性来帮助您发现它们。这是通过有意双重调用以下函数来完成的:...
\n
另外,为了验证您需要提交表单(尝试按enter),如果您在onChange模式下不使用参考,您应该使用triggerValidation。
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}\nRun Code Online (Sandbox Code Playgroud)\n\n
| 归档时间: |
|
| 查看次数: |
4399 次 |
| 最近记录: |