表单输入过程的一个关键部分是表单的提交。当使用第三方库(如React Hook Form)时,这部分的过程总是很有趣。一个常见的基本任务是让用户知道提交成功了。 那么,如何在React Hook Form中做到这一点?让我们来了解一下。

一个例子
我们有一个简单的表单,已经使用React Hook Form实现了。该表单捕获了一个用户的名字:
type FormData = {
name: string;
};
export default function App() {
const { register, handleSubmit, errors } = useForm<FormData>();
const submitForm = async (data: FormData) => {
console.log("Submission starting", data);
const result = await postData(data);
console.log("Submitting complete", result.success);
};
return (
<div className="app">
<form onSubmit={handleSubmit(submitForm)}>
<div>
<input
ref={register({ required: true })}
type="text"
name="name"
placeholder="Enter your name"
/>
</div>
{errors.name && errors.name.type === "required" && (
<div className="error">You must enter your name</div>
)}
</form>
</div>
);
}
表单上的name 字段是强制性的。我们使用React Hook Form中的errors 对象,如果这个字段没有被填入,就输出一个验证错误。
表单提交逻辑调用一个postData 函数,将表单发送到服务器上。下面是我们对postData 的模拟实现:
const postData = ({ name }: FormData): Promise<postDataResult<FormData>> => {
return new Promise((resolve) => {
setTimeout(() => {
console.log(`${name} saved.`);
resolve({ success: true });
}, 100);
});
};
这模拟了对服务器的调用,并返回提交成功的信息。
submitForm 只有在验证通过时才会调用
如果用户在输入任何东西之前按回车键,表单的验证检查就会失败。在这种情况下,我们的submitForm 函数将不会被React Hook Form调用。这意味着submitForm 中的逻辑不需要检查表单是否有效--我们可以假设它是有效的。
很好!
检测表单何时被提交
通常情况下,我们想在提交过程中禁用一个表单。React Hook Form有一个方便的formState 变量,包含表单是否被提交:
const {
register,
handleSubmit,
errors,
formState,} = useForm<FormData>();
我们可以在提交过程中使用它来禁用输入元素:
<input
ref={register({
required: { value: true, message: "You must enter your name" }
})}
type="text"
name="name"
placeholder="Enter your name"
disabled={formState.isSubmitting}/>
我们使用formState 中的isSubmitting 变量来确定表单是否正在被提交,并将其绑定到输入的disabled 属性。
值得注意的是,当formState 发生变化时,表单会被重新渲染。
当提交完成后,isSubmitting 将被设置为false ,这意味着输入元素再次被启用。
检测表单何时被提交
我们想在表单成功提交后向用户呈现一条信息。formState 变量也包含一个isSubmitted 变量。让我们试一试吧:
<form onSubmit={handleSubmit(submitForm)}>
...
{formState.isSubmitted && (
<div className="success">Form submitted successfully</div>
)}
</form>
因此,当isSubmitted 为真时,我们输出一条成功信息。
如果用户在填写他们的名字之前按了回车键,我们就会得到成功信息和验证错误。

这与我们的要求不尽相同!
所以,isSubmitted 只表明表单是否被提交--而不是是否成功提交。这确实有道理,因为React Hook Form只控制了提交的一部分。例如,在提交的过程中,服务器部分可能会发生一些它不知道的问题。
检测表单何时被成功提交
我们需要为表单是否成功提交创建我们自己的状态:
const [
isSuccessfullySubmitted,
setIsSuccessfullySubmitted,
] = React.useState(false);
当表单第一次被加载时,该状态被初始化为false 。
我们在表单被发布到服务器后设置这个状态:
const submitForm = async (data: FormData) => {
console.log("Submission starting", data);
const result = await postData(data);
console.log("Submitting complete", result.success);
setIsSuccessfullySubmitted(result.success);};
然后我们可以使用isSuccessfullySubmitted 来呈现成功信息:
{isSuccessfullySubmitted && (
<div className="success">Form submitted successfully</div>
)}
现在,在用户成功提交表单之前,成功信息不会出现:

酷!我们还可以把 添加到服务器上。
我们还可以在输入元素的disabled 属性绑定中添加isSuccessfullySubmitted ,这样,当表单成功提交后,它就会被禁用:
<input
...
disabled={formState.isSubmitting || isSuccessfullySubmitted}/>
包裹起来
isSubmitted 在React Hook Form的 表示表单是否被提交,而不一定是是否成功提交。我们使用我们自己的状态来表示成功提交,我们可以在提交函数中设置这个状态。 formState