标准答案
- 字段值、touched、dirty、errors、submitting 应该有清晰状态模型,避免散落在多个 useState 中。
- 同步校验适合必填、长度、格式和跨字段规则,提交前和字段交互时都可以触发。
- 异步校验适合用户名占用、邀请码有效性等服务端判断,需要防抖、取消和竞态处理。
- 提交态要禁用重复提交,保留服务端错误,并在成功后明确重置或跳转。
- React Hook Form、Formik、Zod、Yup 等工具可以减少样板,但仍要设计好错误展示和交互时机。
题目解析
这道题要覆盖用户体验和状态一致性。复杂表单最容易出问题的是异步校验竞态和提交中重复操作。
跨字段校验不能只看单个 input,例如确认密码、日期范围、金额上下限都需要整体校验。
服务端错误不应只弹 toast,字段级错误最好回填到对应字段,让用户知道该改哪里。
代码示例
下面用提交态阻止重复提交,并把服务端字段错误回填到表单。
TSX
async function handleSubmit(values: FormValues) {
setSubmitting(true)
setErrors({})
try {
await createAccount(values)
navigate('/account/success')
} catch (error) {
setErrors(toFieldErrors(error))
} finally {
setSubmitting(false)
}
}
return <button disabled={submitting}>提交</button>常见误区
- 异步校验没有取消或防抖,旧结果覆盖新输入的校验状态。
- 只在提交时校验所有字段,用户输入过程中完全没有可恢复提示。
- 提交失败只弹全局错误,不把字段错误映射回具体输入项。