我正在使用react-hook-form为客户端应用程序构建一些用户输入。
用户应该能够更新输入。然后onBlur,react-hook-form就是验证输入并更新一个react useState对象。如果验证失败,外部状态不会更新。
以下代码无法使外部状态对象在Blur上保持最新。
由于 handleSubmit() 函数是异步的,我无法设置状态。
function App() {
const [value, setValue] = useState({
name: "",
});
const { register, handleSubmit } = useForm({ mode: "onBlur" });
return (
<>
{errors?.name ? <p>{errors.name.message}</p> : null}
<label htmlFor="name">Name</label>
<input
{...register("name", {
onBlur: handleSubmit((data) => {
setValue((prev) => ({ ...prev, name: data.name }));
}),
minLength: { value: 2, message: "Name is too short" },
required: { value: true, message: "Name is required" },
})}
id="name"
type="text"
/>
</>
);
}
更新的代码——这对你有用..我已经更新了代码。
import React, { useState } from "react";
import { useForm } from "react-hook-form";
function App() {
const [value, setValue] = useState({
name: "",
});
const {
register,
trigger,
getValues,
formState: { errors },
} = useForm({ mode: "onBlur" });
const handleBlur = async (fieldName) => {
const isValid = await trigger(fieldName); // Validate the field
if (isValid) {
const fieldValue = getValues(fieldName); // Get the current field value
setValue((prev) => ({ ...prev, [fieldName]: fieldValue }));
}
};
return (
<>
{errors?.name && <p>{errors.name.message}</p>}
<label htmlFor="name">Name</label>
<input
{...register("name", {
onBlur: () => handleBlur("name"), // Call the custom blur handler
minLength: { value: 2, message: "Name is too short" },
required: { value: true, message: "Name is required" },
})}
id="name"
type="text"
/>
</>
);
}
export default App;
您的实现中的问题是由于在输入的 onBlur 事件中使用react-hook-form的handleSubmit函数引起的。 handleSubmit 专为表单提交而设计,期望处理整个表单而不是单个字段。
为了创建单独的字段并更新外部状态,我将使用react-hook-form中的触发器进行字段级验证。触发方法可以通过编程方式验证特定字段,如果验证通过,您就可以安全地更新外部状态。
我会做什么:
import { useForm } from "react-hook-form";
function App() {
const [value, setValue] = useState({
name: "",
});
const {
register,
trigger,
getValues,
formState: { errors },
} = useForm({ mode: "onBlur" });
const handleBlur = async () => {
const isValid = await trigger("name"); // Trigger validation
if (isValid) {
const updatedValue = getValues("name"); // Get the current value
setValue((prev) => ({ ...prev, name: updatedValue }));
}
};
return (
<>
{errors?.name ? <p>{errors.name.message}</p> : null}
<label htmlFor="name">Name</label>
<input
{...register("name", {
minLength: { value: 2, message: "Name is too short" },
required: { value: true, message: "Name is required" },
})}
id="name"
type="text"
onBlur={handleBlur}
/>
<p>External State: {value.name}</p>
</>
);
}
export default App;